xref: /aosp_15_r20/external/clang/lib/Driver/Tools.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li //===--- Tools.cpp - Tools Implementations ----------------------*- C++ -*-===//
2*67e74705SXin Li //
3*67e74705SXin Li //                     The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===----------------------------------------------------------------------===//
9*67e74705SXin Li 
10*67e74705SXin Li #include "Tools.h"
11*67e74705SXin Li #include "InputInfo.h"
12*67e74705SXin Li #include "ToolChains.h"
13*67e74705SXin Li #include "clang/Basic/CharInfo.h"
14*67e74705SXin Li #include "clang/Basic/LangOptions.h"
15*67e74705SXin Li #include "clang/Basic/ObjCRuntime.h"
16*67e74705SXin Li #include "clang/Basic/Version.h"
17*67e74705SXin Li #include "clang/Config/config.h"
18*67e74705SXin Li #include "clang/Driver/Action.h"
19*67e74705SXin Li #include "clang/Driver/Compilation.h"
20*67e74705SXin Li #include "clang/Driver/Driver.h"
21*67e74705SXin Li #include "clang/Driver/DriverDiagnostic.h"
22*67e74705SXin Li #include "clang/Driver/Job.h"
23*67e74705SXin Li #include "clang/Driver/Options.h"
24*67e74705SXin Li #include "clang/Driver/SanitizerArgs.h"
25*67e74705SXin Li #include "clang/Driver/ToolChain.h"
26*67e74705SXin Li #include "clang/Driver/Util.h"
27*67e74705SXin Li #include "llvm/ADT/STLExtras.h"
28*67e74705SXin Li #include "llvm/ADT/SmallString.h"
29*67e74705SXin Li #include "llvm/ADT/StringExtras.h"
30*67e74705SXin Li #include "llvm/ADT/StringSwitch.h"
31*67e74705SXin Li #include "llvm/ADT/Twine.h"
32*67e74705SXin Li #include "llvm/Option/Arg.h"
33*67e74705SXin Li #include "llvm/Option/ArgList.h"
34*67e74705SXin Li #include "llvm/Option/Option.h"
35*67e74705SXin Li #include "llvm/Support/CodeGen.h"
36*67e74705SXin Li #include "llvm/Support/Compression.h"
37*67e74705SXin Li #include "llvm/Support/ErrorHandling.h"
38*67e74705SXin Li #include "llvm/Support/FileSystem.h"
39*67e74705SXin Li #include "llvm/Support/Host.h"
40*67e74705SXin Li #include "llvm/Support/Path.h"
41*67e74705SXin Li #include "llvm/Support/Process.h"
42*67e74705SXin Li #include "llvm/Support/Program.h"
43*67e74705SXin Li #include "llvm/Support/raw_ostream.h"
44*67e74705SXin Li #include "llvm/Support/TargetParser.h"
45*67e74705SXin Li 
46*67e74705SXin Li #ifdef LLVM_ON_UNIX
47*67e74705SXin Li #include <unistd.h> // For getuid().
48*67e74705SXin Li #endif
49*67e74705SXin Li 
50*67e74705SXin Li using namespace clang::driver;
51*67e74705SXin Li using namespace clang::driver::tools;
52*67e74705SXin Li using namespace clang;
53*67e74705SXin Li using namespace llvm::opt;
54*67e74705SXin Li 
handleTargetFeaturesGroup(const ArgList & Args,std::vector<const char * > & Features,OptSpecifier Group)55*67e74705SXin Li static void handleTargetFeaturesGroup(const ArgList &Args,
56*67e74705SXin Li                                       std::vector<const char *> &Features,
57*67e74705SXin Li                                       OptSpecifier Group) {
58*67e74705SXin Li   for (const Arg *A : Args.filtered(Group)) {
59*67e74705SXin Li     StringRef Name = A->getOption().getName();
60*67e74705SXin Li     A->claim();
61*67e74705SXin Li 
62*67e74705SXin Li     // Skip over "-m".
63*67e74705SXin Li     assert(Name.startswith("m") && "Invalid feature name.");
64*67e74705SXin Li     Name = Name.substr(1);
65*67e74705SXin Li 
66*67e74705SXin Li     bool IsNegative = Name.startswith("no-");
67*67e74705SXin Li     if (IsNegative)
68*67e74705SXin Li       Name = Name.substr(3);
69*67e74705SXin Li     Features.push_back(Args.MakeArgString((IsNegative ? "-" : "+") + Name));
70*67e74705SXin Li   }
71*67e74705SXin Li }
72*67e74705SXin Li 
getSparcAsmModeForCPU(StringRef Name,const llvm::Triple & Triple)73*67e74705SXin Li static const char *getSparcAsmModeForCPU(StringRef Name,
74*67e74705SXin Li                                          const llvm::Triple &Triple) {
75*67e74705SXin Li   if (Triple.getArch() == llvm::Triple::sparcv9) {
76*67e74705SXin Li     return llvm::StringSwitch<const char *>(Name)
77*67e74705SXin Li           .Case("niagara", "-Av9b")
78*67e74705SXin Li           .Case("niagara2", "-Av9b")
79*67e74705SXin Li           .Case("niagara3", "-Av9d")
80*67e74705SXin Li           .Case("niagara4", "-Av9d")
81*67e74705SXin Li           .Default("-Av9");
82*67e74705SXin Li   } else {
83*67e74705SXin Li     return llvm::StringSwitch<const char *>(Name)
84*67e74705SXin Li           .Case("v8", "-Av8")
85*67e74705SXin Li           .Case("supersparc", "-Av8")
86*67e74705SXin Li           .Case("sparclite", "-Asparclite")
87*67e74705SXin Li           .Case("f934", "-Asparclite")
88*67e74705SXin Li           .Case("hypersparc", "-Av8")
89*67e74705SXin Li           .Case("sparclite86x", "-Asparclite")
90*67e74705SXin Li           .Case("sparclet", "-Asparclet")
91*67e74705SXin Li           .Case("tsc701", "-Asparclet")
92*67e74705SXin Li           .Case("v9", "-Av8plus")
93*67e74705SXin Li           .Case("ultrasparc", "-Av8plus")
94*67e74705SXin Li           .Case("ultrasparc3", "-Av8plus")
95*67e74705SXin Li           .Case("niagara", "-Av8plusb")
96*67e74705SXin Li           .Case("niagara2", "-Av8plusb")
97*67e74705SXin Li           .Case("niagara3", "-Av8plusd")
98*67e74705SXin Li           .Case("niagara4", "-Av8plusd")
99*67e74705SXin Li           .Case("leon2", "-Av8")
100*67e74705SXin Li           .Case("at697e", "-Av8")
101*67e74705SXin Li           .Case("at697f", "-Av8")
102*67e74705SXin Li           .Case("leon3", "-Av8")
103*67e74705SXin Li           .Case("ut699", "-Av8")
104*67e74705SXin Li           .Case("gr712rc", "-Av8")
105*67e74705SXin Li           .Case("leon4", "-Av8")
106*67e74705SXin Li           .Case("gr740", "-Av8")
107*67e74705SXin Li           .Default("-Av8");
108*67e74705SXin Li   }
109*67e74705SXin Li }
110*67e74705SXin Li 
111*67e74705SXin Li /// CheckPreprocessingOptions - Perform some validation of preprocessing
112*67e74705SXin Li /// arguments that is shared with gcc.
CheckPreprocessingOptions(const Driver & D,const ArgList & Args)113*67e74705SXin Li static void CheckPreprocessingOptions(const Driver &D, const ArgList &Args) {
114*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_C, options::OPT_CC)) {
115*67e74705SXin Li     if (!Args.hasArg(options::OPT_E) && !Args.hasArg(options::OPT__SLASH_P) &&
116*67e74705SXin Li         !Args.hasArg(options::OPT__SLASH_EP) && !D.CCCIsCPP()) {
117*67e74705SXin Li       D.Diag(diag::err_drv_argument_only_allowed_with)
118*67e74705SXin Li           << A->getBaseArg().getAsString(Args)
119*67e74705SXin Li           << (D.IsCLMode() ? "/E, /P or /EP" : "-E");
120*67e74705SXin Li     }
121*67e74705SXin Li   }
122*67e74705SXin Li }
123*67e74705SXin Li 
124*67e74705SXin Li /// CheckCodeGenerationOptions - Perform some validation of code generation
125*67e74705SXin Li /// arguments that is shared with gcc.
CheckCodeGenerationOptions(const Driver & D,const ArgList & Args)126*67e74705SXin Li static void CheckCodeGenerationOptions(const Driver &D, const ArgList &Args) {
127*67e74705SXin Li   // In gcc, only ARM checks this, but it seems reasonable to check universally.
128*67e74705SXin Li   if (Args.hasArg(options::OPT_static))
129*67e74705SXin Li     if (const Arg *A =
130*67e74705SXin Li             Args.getLastArg(options::OPT_dynamic, options::OPT_mdynamic_no_pic))
131*67e74705SXin Li       D.Diag(diag::err_drv_argument_not_allowed_with) << A->getAsString(Args)
132*67e74705SXin Li                                                       << "-static";
133*67e74705SXin Li }
134*67e74705SXin Li 
135*67e74705SXin Li // Add backslashes to escape spaces and other backslashes.
136*67e74705SXin Li // This is used for the space-separated argument list specified with
137*67e74705SXin Li // the -dwarf-debug-flags option.
EscapeSpacesAndBackslashes(const char * Arg,SmallVectorImpl<char> & Res)138*67e74705SXin Li static void EscapeSpacesAndBackslashes(const char *Arg,
139*67e74705SXin Li                                        SmallVectorImpl<char> &Res) {
140*67e74705SXin Li   for (; *Arg; ++Arg) {
141*67e74705SXin Li     switch (*Arg) {
142*67e74705SXin Li     default:
143*67e74705SXin Li       break;
144*67e74705SXin Li     case ' ':
145*67e74705SXin Li     case '\\':
146*67e74705SXin Li       Res.push_back('\\');
147*67e74705SXin Li       break;
148*67e74705SXin Li     }
149*67e74705SXin Li     Res.push_back(*Arg);
150*67e74705SXin Li   }
151*67e74705SXin Li }
152*67e74705SXin Li 
153*67e74705SXin Li // Quote target names for inclusion in GNU Make dependency files.
154*67e74705SXin Li // Only the characters '$', '#', ' ', '\t' are quoted.
QuoteTarget(StringRef Target,SmallVectorImpl<char> & Res)155*67e74705SXin Li static void QuoteTarget(StringRef Target, SmallVectorImpl<char> &Res) {
156*67e74705SXin Li   for (unsigned i = 0, e = Target.size(); i != e; ++i) {
157*67e74705SXin Li     switch (Target[i]) {
158*67e74705SXin Li     case ' ':
159*67e74705SXin Li     case '\t':
160*67e74705SXin Li       // Escape the preceding backslashes
161*67e74705SXin Li       for (int j = i - 1; j >= 0 && Target[j] == '\\'; --j)
162*67e74705SXin Li         Res.push_back('\\');
163*67e74705SXin Li 
164*67e74705SXin Li       // Escape the space/tab
165*67e74705SXin Li       Res.push_back('\\');
166*67e74705SXin Li       break;
167*67e74705SXin Li     case '$':
168*67e74705SXin Li       Res.push_back('$');
169*67e74705SXin Li       break;
170*67e74705SXin Li     case '#':
171*67e74705SXin Li       Res.push_back('\\');
172*67e74705SXin Li       break;
173*67e74705SXin Li     default:
174*67e74705SXin Li       break;
175*67e74705SXin Li     }
176*67e74705SXin Li 
177*67e74705SXin Li     Res.push_back(Target[i]);
178*67e74705SXin Li   }
179*67e74705SXin Li }
180*67e74705SXin Li 
addDirectoryList(const ArgList & Args,ArgStringList & CmdArgs,const char * ArgName,const char * EnvVar)181*67e74705SXin Li static void addDirectoryList(const ArgList &Args, ArgStringList &CmdArgs,
182*67e74705SXin Li                              const char *ArgName, const char *EnvVar) {
183*67e74705SXin Li   const char *DirList = ::getenv(EnvVar);
184*67e74705SXin Li   bool CombinedArg = false;
185*67e74705SXin Li 
186*67e74705SXin Li   if (!DirList)
187*67e74705SXin Li     return; // Nothing to do.
188*67e74705SXin Li 
189*67e74705SXin Li   StringRef Name(ArgName);
190*67e74705SXin Li   if (Name.equals("-I") || Name.equals("-L"))
191*67e74705SXin Li     CombinedArg = true;
192*67e74705SXin Li 
193*67e74705SXin Li   StringRef Dirs(DirList);
194*67e74705SXin Li   if (Dirs.empty()) // Empty string should not add '.'.
195*67e74705SXin Li     return;
196*67e74705SXin Li 
197*67e74705SXin Li   StringRef::size_type Delim;
198*67e74705SXin Li   while ((Delim = Dirs.find(llvm::sys::EnvPathSeparator)) != StringRef::npos) {
199*67e74705SXin Li     if (Delim == 0) { // Leading colon.
200*67e74705SXin Li       if (CombinedArg) {
201*67e74705SXin Li         CmdArgs.push_back(Args.MakeArgString(std::string(ArgName) + "."));
202*67e74705SXin Li       } else {
203*67e74705SXin Li         CmdArgs.push_back(ArgName);
204*67e74705SXin Li         CmdArgs.push_back(".");
205*67e74705SXin Li       }
206*67e74705SXin Li     } else {
207*67e74705SXin Li       if (CombinedArg) {
208*67e74705SXin Li         CmdArgs.push_back(
209*67e74705SXin Li             Args.MakeArgString(std::string(ArgName) + Dirs.substr(0, Delim)));
210*67e74705SXin Li       } else {
211*67e74705SXin Li         CmdArgs.push_back(ArgName);
212*67e74705SXin Li         CmdArgs.push_back(Args.MakeArgString(Dirs.substr(0, Delim)));
213*67e74705SXin Li       }
214*67e74705SXin Li     }
215*67e74705SXin Li     Dirs = Dirs.substr(Delim + 1);
216*67e74705SXin Li   }
217*67e74705SXin Li 
218*67e74705SXin Li   if (Dirs.empty()) { // Trailing colon.
219*67e74705SXin Li     if (CombinedArg) {
220*67e74705SXin Li       CmdArgs.push_back(Args.MakeArgString(std::string(ArgName) + "."));
221*67e74705SXin Li     } else {
222*67e74705SXin Li       CmdArgs.push_back(ArgName);
223*67e74705SXin Li       CmdArgs.push_back(".");
224*67e74705SXin Li     }
225*67e74705SXin Li   } else { // Add the last path.
226*67e74705SXin Li     if (CombinedArg) {
227*67e74705SXin Li       CmdArgs.push_back(Args.MakeArgString(std::string(ArgName) + Dirs));
228*67e74705SXin Li     } else {
229*67e74705SXin Li       CmdArgs.push_back(ArgName);
230*67e74705SXin Li       CmdArgs.push_back(Args.MakeArgString(Dirs));
231*67e74705SXin Li     }
232*67e74705SXin Li   }
233*67e74705SXin Li }
234*67e74705SXin Li 
AddLinkerInputs(const ToolChain & TC,const InputInfoList & Inputs,const ArgList & Args,ArgStringList & CmdArgs)235*67e74705SXin Li static void AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs,
236*67e74705SXin Li                             const ArgList &Args, ArgStringList &CmdArgs) {
237*67e74705SXin Li   const Driver &D = TC.getDriver();
238*67e74705SXin Li 
239*67e74705SXin Li   // Add extra linker input arguments which are not treated as inputs
240*67e74705SXin Li   // (constructed via -Xarch_).
241*67e74705SXin Li   Args.AddAllArgValues(CmdArgs, options::OPT_Zlinker_input);
242*67e74705SXin Li 
243*67e74705SXin Li   for (const auto &II : Inputs) {
244*67e74705SXin Li     if (!TC.HasNativeLLVMSupport() && types::isLLVMIR(II.getType()))
245*67e74705SXin Li       // Don't try to pass LLVM inputs unless we have native support.
246*67e74705SXin Li       D.Diag(diag::err_drv_no_linker_llvm_support) << TC.getTripleString();
247*67e74705SXin Li 
248*67e74705SXin Li     // Add filenames immediately.
249*67e74705SXin Li     if (II.isFilename()) {
250*67e74705SXin Li       CmdArgs.push_back(II.getFilename());
251*67e74705SXin Li       continue;
252*67e74705SXin Li     }
253*67e74705SXin Li 
254*67e74705SXin Li     // Otherwise, this is a linker input argument.
255*67e74705SXin Li     const Arg &A = II.getInputArg();
256*67e74705SXin Li 
257*67e74705SXin Li     // Handle reserved library options.
258*67e74705SXin Li     if (A.getOption().matches(options::OPT_Z_reserved_lib_stdcxx))
259*67e74705SXin Li       TC.AddCXXStdlibLibArgs(Args, CmdArgs);
260*67e74705SXin Li     else if (A.getOption().matches(options::OPT_Z_reserved_lib_cckext))
261*67e74705SXin Li       TC.AddCCKextLibArgs(Args, CmdArgs);
262*67e74705SXin Li     else if (A.getOption().matches(options::OPT_z)) {
263*67e74705SXin Li       // Pass -z prefix for gcc linker compatibility.
264*67e74705SXin Li       A.claim();
265*67e74705SXin Li       A.render(Args, CmdArgs);
266*67e74705SXin Li     } else {
267*67e74705SXin Li       A.renderAsInput(Args, CmdArgs);
268*67e74705SXin Li     }
269*67e74705SXin Li   }
270*67e74705SXin Li 
271*67e74705SXin Li   // LIBRARY_PATH - included following the user specified library paths.
272*67e74705SXin Li   //                and only supported on native toolchains.
273*67e74705SXin Li   if (!TC.isCrossCompiling())
274*67e74705SXin Li     addDirectoryList(Args, CmdArgs, "-L", "LIBRARY_PATH");
275*67e74705SXin Li }
276*67e74705SXin Li 
277*67e74705SXin Li /// \brief Determine whether Objective-C automated reference counting is
278*67e74705SXin Li /// enabled.
isObjCAutoRefCount(const ArgList & Args)279*67e74705SXin Li static bool isObjCAutoRefCount(const ArgList &Args) {
280*67e74705SXin Li   return Args.hasFlag(options::OPT_fobjc_arc, options::OPT_fno_objc_arc, false);
281*67e74705SXin Li }
282*67e74705SXin Li 
283*67e74705SXin Li /// \brief Determine whether we are linking the ObjC runtime.
isObjCRuntimeLinked(const ArgList & Args)284*67e74705SXin Li static bool isObjCRuntimeLinked(const ArgList &Args) {
285*67e74705SXin Li   if (isObjCAutoRefCount(Args)) {
286*67e74705SXin Li     Args.ClaimAllArgs(options::OPT_fobjc_link_runtime);
287*67e74705SXin Li     return true;
288*67e74705SXin Li   }
289*67e74705SXin Li   return Args.hasArg(options::OPT_fobjc_link_runtime);
290*67e74705SXin Li }
291*67e74705SXin Li 
forwardToGCC(const Option & O)292*67e74705SXin Li static bool forwardToGCC(const Option &O) {
293*67e74705SXin Li   // Don't forward inputs from the original command line.  They are added from
294*67e74705SXin Li   // InputInfoList.
295*67e74705SXin Li   return O.getKind() != Option::InputClass &&
296*67e74705SXin Li          !O.hasFlag(options::DriverOption) && !O.hasFlag(options::LinkerInput);
297*67e74705SXin Li }
298*67e74705SXin Li 
AddPreprocessingOptions(Compilation & C,const JobAction & JA,const Driver & D,const ArgList & Args,ArgStringList & CmdArgs,const InputInfo & Output,const InputInfoList & Inputs,const ToolChain * AuxToolChain) const299*67e74705SXin Li void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA,
300*67e74705SXin Li                                     const Driver &D, const ArgList &Args,
301*67e74705SXin Li                                     ArgStringList &CmdArgs,
302*67e74705SXin Li                                     const InputInfo &Output,
303*67e74705SXin Li                                     const InputInfoList &Inputs,
304*67e74705SXin Li                                     const ToolChain *AuxToolChain) const {
305*67e74705SXin Li   Arg *A;
306*67e74705SXin Li   const bool IsIAMCU = getToolChain().getTriple().isOSIAMCU();
307*67e74705SXin Li 
308*67e74705SXin Li   CheckPreprocessingOptions(D, Args);
309*67e74705SXin Li 
310*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_C);
311*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_CC);
312*67e74705SXin Li 
313*67e74705SXin Li   // Handle dependency file generation.
314*67e74705SXin Li   if ((A = Args.getLastArg(options::OPT_M, options::OPT_MM)) ||
315*67e74705SXin Li       (A = Args.getLastArg(options::OPT_MD)) ||
316*67e74705SXin Li       (A = Args.getLastArg(options::OPT_MMD))) {
317*67e74705SXin Li     // Determine the output location.
318*67e74705SXin Li     const char *DepFile;
319*67e74705SXin Li     if (Arg *MF = Args.getLastArg(options::OPT_MF)) {
320*67e74705SXin Li       DepFile = MF->getValue();
321*67e74705SXin Li       C.addFailureResultFile(DepFile, &JA);
322*67e74705SXin Li     } else if (Output.getType() == types::TY_Dependencies) {
323*67e74705SXin Li       DepFile = Output.getFilename();
324*67e74705SXin Li     } else if (A->getOption().matches(options::OPT_M) ||
325*67e74705SXin Li                A->getOption().matches(options::OPT_MM)) {
326*67e74705SXin Li       DepFile = "-";
327*67e74705SXin Li     } else {
328*67e74705SXin Li       DepFile = getDependencyFileName(Args, Inputs);
329*67e74705SXin Li       C.addFailureResultFile(DepFile, &JA);
330*67e74705SXin Li     }
331*67e74705SXin Li     CmdArgs.push_back("-dependency-file");
332*67e74705SXin Li     CmdArgs.push_back(DepFile);
333*67e74705SXin Li 
334*67e74705SXin Li     // Add a default target if one wasn't specified.
335*67e74705SXin Li     if (!Args.hasArg(options::OPT_MT) && !Args.hasArg(options::OPT_MQ)) {
336*67e74705SXin Li       const char *DepTarget;
337*67e74705SXin Li 
338*67e74705SXin Li       // If user provided -o, that is the dependency target, except
339*67e74705SXin Li       // when we are only generating a dependency file.
340*67e74705SXin Li       Arg *OutputOpt = Args.getLastArg(options::OPT_o);
341*67e74705SXin Li       if (OutputOpt && Output.getType() != types::TY_Dependencies) {
342*67e74705SXin Li         DepTarget = OutputOpt->getValue();
343*67e74705SXin Li       } else {
344*67e74705SXin Li         // Otherwise derive from the base input.
345*67e74705SXin Li         //
346*67e74705SXin Li         // FIXME: This should use the computed output file location.
347*67e74705SXin Li         SmallString<128> P(Inputs[0].getBaseInput());
348*67e74705SXin Li         llvm::sys::path::replace_extension(P, "o");
349*67e74705SXin Li         DepTarget = Args.MakeArgString(llvm::sys::path::filename(P));
350*67e74705SXin Li       }
351*67e74705SXin Li 
352*67e74705SXin Li       CmdArgs.push_back("-MT");
353*67e74705SXin Li       SmallString<128> Quoted;
354*67e74705SXin Li       QuoteTarget(DepTarget, Quoted);
355*67e74705SXin Li       CmdArgs.push_back(Args.MakeArgString(Quoted));
356*67e74705SXin Li     }
357*67e74705SXin Li 
358*67e74705SXin Li     if (A->getOption().matches(options::OPT_M) ||
359*67e74705SXin Li         A->getOption().matches(options::OPT_MD))
360*67e74705SXin Li       CmdArgs.push_back("-sys-header-deps");
361*67e74705SXin Li     if ((isa<PrecompileJobAction>(JA) &&
362*67e74705SXin Li          !Args.hasArg(options::OPT_fno_module_file_deps)) ||
363*67e74705SXin Li         Args.hasArg(options::OPT_fmodule_file_deps))
364*67e74705SXin Li       CmdArgs.push_back("-module-file-deps");
365*67e74705SXin Li   }
366*67e74705SXin Li 
367*67e74705SXin Li   if (Args.hasArg(options::OPT_MG)) {
368*67e74705SXin Li     if (!A || A->getOption().matches(options::OPT_MD) ||
369*67e74705SXin Li         A->getOption().matches(options::OPT_MMD))
370*67e74705SXin Li       D.Diag(diag::err_drv_mg_requires_m_or_mm);
371*67e74705SXin Li     CmdArgs.push_back("-MG");
372*67e74705SXin Li   }
373*67e74705SXin Li 
374*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_MP);
375*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_MV);
376*67e74705SXin Li 
377*67e74705SXin Li   // Convert all -MQ <target> args to -MT <quoted target>
378*67e74705SXin Li   for (const Arg *A : Args.filtered(options::OPT_MT, options::OPT_MQ)) {
379*67e74705SXin Li     A->claim();
380*67e74705SXin Li 
381*67e74705SXin Li     if (A->getOption().matches(options::OPT_MQ)) {
382*67e74705SXin Li       CmdArgs.push_back("-MT");
383*67e74705SXin Li       SmallString<128> Quoted;
384*67e74705SXin Li       QuoteTarget(A->getValue(), Quoted);
385*67e74705SXin Li       CmdArgs.push_back(Args.MakeArgString(Quoted));
386*67e74705SXin Li 
387*67e74705SXin Li       // -MT flag - no change
388*67e74705SXin Li     } else {
389*67e74705SXin Li       A->render(Args, CmdArgs);
390*67e74705SXin Li     }
391*67e74705SXin Li   }
392*67e74705SXin Li 
393*67e74705SXin Li   // Add -i* options, and automatically translate to
394*67e74705SXin Li   // -include-pch/-include-pth for transparent PCH support. It's
395*67e74705SXin Li   // wonky, but we include looking for .gch so we can support seamless
396*67e74705SXin Li   // replacement into a build system already set up to be generating
397*67e74705SXin Li   // .gch files.
398*67e74705SXin Li   int YcIndex = -1, YuIndex = -1;
399*67e74705SXin Li   {
400*67e74705SXin Li     int AI = -1;
401*67e74705SXin Li     const Arg *YcArg = Args.getLastArg(options::OPT__SLASH_Yc);
402*67e74705SXin Li     const Arg *YuArg = Args.getLastArg(options::OPT__SLASH_Yu);
403*67e74705SXin Li     for (const Arg *A : Args.filtered(options::OPT_clang_i_Group)) {
404*67e74705SXin Li       // Walk the whole i_Group and skip non "-include" flags so that the index
405*67e74705SXin Li       // here matches the index in the next loop below.
406*67e74705SXin Li       ++AI;
407*67e74705SXin Li       if (!A->getOption().matches(options::OPT_include))
408*67e74705SXin Li         continue;
409*67e74705SXin Li       if (YcArg && strcmp(A->getValue(), YcArg->getValue()) == 0)
410*67e74705SXin Li         YcIndex = AI;
411*67e74705SXin Li       if (YuArg && strcmp(A->getValue(), YuArg->getValue()) == 0)
412*67e74705SXin Li         YuIndex = AI;
413*67e74705SXin Li     }
414*67e74705SXin Li   }
415*67e74705SXin Li   if (isa<PrecompileJobAction>(JA) && YcIndex != -1) {
416*67e74705SXin Li     Driver::InputList Inputs;
417*67e74705SXin Li     D.BuildInputs(getToolChain(), C.getArgs(), Inputs);
418*67e74705SXin Li     assert(Inputs.size() == 1 && "Need one input when building pch");
419*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(Twine("-find-pch-source=") +
420*67e74705SXin Li                                          Inputs[0].second->getValue()));
421*67e74705SXin Li   }
422*67e74705SXin Li 
423*67e74705SXin Li   bool RenderedImplicitInclude = false;
424*67e74705SXin Li   int AI = -1;
425*67e74705SXin Li   for (const Arg *A : Args.filtered(options::OPT_clang_i_Group)) {
426*67e74705SXin Li     ++AI;
427*67e74705SXin Li 
428*67e74705SXin Li     if (getToolChain().getDriver().IsCLMode() &&
429*67e74705SXin Li         A->getOption().matches(options::OPT_include)) {
430*67e74705SXin Li       // In clang-cl mode, /Ycfoo.h means that all code up to a foo.h
431*67e74705SXin Li       // include is compiled into foo.h, and everything after goes into
432*67e74705SXin Li       // the .obj file. /Yufoo.h means that all includes prior to and including
433*67e74705SXin Li       // foo.h are completely skipped and replaced with a use of the pch file
434*67e74705SXin Li       // for foo.h.  (Each flag can have at most one value, multiple /Yc flags
435*67e74705SXin Li       // just mean that the last one wins.)  If /Yc and /Yu are both present
436*67e74705SXin Li       // and refer to the same file, /Yc wins.
437*67e74705SXin Li       // Note that OPT__SLASH_FI gets mapped to OPT_include.
438*67e74705SXin Li       // FIXME: The code here assumes that /Yc and /Yu refer to the same file.
439*67e74705SXin Li       // cl.exe seems to support both flags with different values, but that
440*67e74705SXin Li       // seems strange (which flag does /Fp now refer to?), so don't implement
441*67e74705SXin Li       // that until someone needs it.
442*67e74705SXin Li       int PchIndex = YcIndex != -1 ? YcIndex : YuIndex;
443*67e74705SXin Li       if (PchIndex != -1) {
444*67e74705SXin Li         if (isa<PrecompileJobAction>(JA)) {
445*67e74705SXin Li           // When building the pch, skip all includes after the pch.
446*67e74705SXin Li           assert(YcIndex != -1 && PchIndex == YcIndex);
447*67e74705SXin Li           if (AI >= YcIndex)
448*67e74705SXin Li             continue;
449*67e74705SXin Li         } else {
450*67e74705SXin Li           // When using the pch, skip all includes prior to the pch.
451*67e74705SXin Li           if (AI < PchIndex) {
452*67e74705SXin Li             A->claim();
453*67e74705SXin Li             continue;
454*67e74705SXin Li           }
455*67e74705SXin Li           if (AI == PchIndex) {
456*67e74705SXin Li             A->claim();
457*67e74705SXin Li             CmdArgs.push_back("-include-pch");
458*67e74705SXin Li             CmdArgs.push_back(
459*67e74705SXin Li                 Args.MakeArgString(D.GetClPchPath(C, A->getValue())));
460*67e74705SXin Li             continue;
461*67e74705SXin Li           }
462*67e74705SXin Li         }
463*67e74705SXin Li       }
464*67e74705SXin Li     } else if (A->getOption().matches(options::OPT_include)) {
465*67e74705SXin Li       // Handling of gcc-style gch precompiled headers.
466*67e74705SXin Li       bool IsFirstImplicitInclude = !RenderedImplicitInclude;
467*67e74705SXin Li       RenderedImplicitInclude = true;
468*67e74705SXin Li 
469*67e74705SXin Li       // Use PCH if the user requested it.
470*67e74705SXin Li       bool UsePCH = D.CCCUsePCH;
471*67e74705SXin Li 
472*67e74705SXin Li       bool FoundPTH = false;
473*67e74705SXin Li       bool FoundPCH = false;
474*67e74705SXin Li       SmallString<128> P(A->getValue());
475*67e74705SXin Li       // We want the files to have a name like foo.h.pch. Add a dummy extension
476*67e74705SXin Li       // so that replace_extension does the right thing.
477*67e74705SXin Li       P += ".dummy";
478*67e74705SXin Li       if (UsePCH) {
479*67e74705SXin Li         llvm::sys::path::replace_extension(P, "pch");
480*67e74705SXin Li         if (llvm::sys::fs::exists(P))
481*67e74705SXin Li           FoundPCH = true;
482*67e74705SXin Li       }
483*67e74705SXin Li 
484*67e74705SXin Li       if (!FoundPCH) {
485*67e74705SXin Li         llvm::sys::path::replace_extension(P, "pth");
486*67e74705SXin Li         if (llvm::sys::fs::exists(P))
487*67e74705SXin Li           FoundPTH = true;
488*67e74705SXin Li       }
489*67e74705SXin Li 
490*67e74705SXin Li       if (!FoundPCH && !FoundPTH) {
491*67e74705SXin Li         llvm::sys::path::replace_extension(P, "gch");
492*67e74705SXin Li         if (llvm::sys::fs::exists(P)) {
493*67e74705SXin Li           FoundPCH = UsePCH;
494*67e74705SXin Li           FoundPTH = !UsePCH;
495*67e74705SXin Li         }
496*67e74705SXin Li       }
497*67e74705SXin Li 
498*67e74705SXin Li       if (FoundPCH || FoundPTH) {
499*67e74705SXin Li         if (IsFirstImplicitInclude) {
500*67e74705SXin Li           A->claim();
501*67e74705SXin Li           if (UsePCH)
502*67e74705SXin Li             CmdArgs.push_back("-include-pch");
503*67e74705SXin Li           else
504*67e74705SXin Li             CmdArgs.push_back("-include-pth");
505*67e74705SXin Li           CmdArgs.push_back(Args.MakeArgString(P));
506*67e74705SXin Li           continue;
507*67e74705SXin Li         } else {
508*67e74705SXin Li           // Ignore the PCH if not first on command line and emit warning.
509*67e74705SXin Li           D.Diag(diag::warn_drv_pch_not_first_include) << P
510*67e74705SXin Li                                                        << A->getAsString(Args);
511*67e74705SXin Li         }
512*67e74705SXin Li       }
513*67e74705SXin Li     } else if (A->getOption().matches(options::OPT_isystem_after)) {
514*67e74705SXin Li       // Handling of paths which must come late.  These entries are handled by
515*67e74705SXin Li       // the toolchain itself after the resource dir is inserted in the right
516*67e74705SXin Li       // search order.
517*67e74705SXin Li       // Do not claim the argument so that the use of the argument does not
518*67e74705SXin Li       // silently go unnoticed on toolchains which do not honour the option.
519*67e74705SXin Li       continue;
520*67e74705SXin Li     }
521*67e74705SXin Li 
522*67e74705SXin Li     // Not translated, render as usual.
523*67e74705SXin Li     A->claim();
524*67e74705SXin Li     A->render(Args, CmdArgs);
525*67e74705SXin Li   }
526*67e74705SXin Li 
527*67e74705SXin Li   Args.AddAllArgs(CmdArgs,
528*67e74705SXin Li                   {options::OPT_D, options::OPT_U, options::OPT_I_Group,
529*67e74705SXin Li                    options::OPT_F, options::OPT_index_header_map});
530*67e74705SXin Li 
531*67e74705SXin Li   // Add -Wp, and -Xpreprocessor if using the preprocessor.
532*67e74705SXin Li 
533*67e74705SXin Li   // FIXME: There is a very unfortunate problem here, some troubled
534*67e74705SXin Li   // souls abuse -Wp, to pass preprocessor options in gcc syntax. To
535*67e74705SXin Li   // really support that we would have to parse and then translate
536*67e74705SXin Li   // those options. :(
537*67e74705SXin Li   Args.AddAllArgValues(CmdArgs, options::OPT_Wp_COMMA,
538*67e74705SXin Li                        options::OPT_Xpreprocessor);
539*67e74705SXin Li 
540*67e74705SXin Li   // -I- is a deprecated GCC feature, reject it.
541*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_I_))
542*67e74705SXin Li     D.Diag(diag::err_drv_I_dash_not_supported) << A->getAsString(Args);
543*67e74705SXin Li 
544*67e74705SXin Li   // If we have a --sysroot, and don't have an explicit -isysroot flag, add an
545*67e74705SXin Li   // -isysroot to the CC1 invocation.
546*67e74705SXin Li   StringRef sysroot = C.getSysRoot();
547*67e74705SXin Li   if (sysroot != "") {
548*67e74705SXin Li     if (!Args.hasArg(options::OPT_isysroot)) {
549*67e74705SXin Li       CmdArgs.push_back("-isysroot");
550*67e74705SXin Li       CmdArgs.push_back(C.getArgs().MakeArgString(sysroot));
551*67e74705SXin Li     }
552*67e74705SXin Li   }
553*67e74705SXin Li 
554*67e74705SXin Li   // Parse additional include paths from environment variables.
555*67e74705SXin Li   // FIXME: We should probably sink the logic for handling these from the
556*67e74705SXin Li   // frontend into the driver. It will allow deleting 4 otherwise unused flags.
557*67e74705SXin Li   // CPATH - included following the user specified includes (but prior to
558*67e74705SXin Li   // builtin and standard includes).
559*67e74705SXin Li   addDirectoryList(Args, CmdArgs, "-I", "CPATH");
560*67e74705SXin Li   // C_INCLUDE_PATH - system includes enabled when compiling C.
561*67e74705SXin Li   addDirectoryList(Args, CmdArgs, "-c-isystem", "C_INCLUDE_PATH");
562*67e74705SXin Li   // CPLUS_INCLUDE_PATH - system includes enabled when compiling C++.
563*67e74705SXin Li   addDirectoryList(Args, CmdArgs, "-cxx-isystem", "CPLUS_INCLUDE_PATH");
564*67e74705SXin Li   // OBJC_INCLUDE_PATH - system includes enabled when compiling ObjC.
565*67e74705SXin Li   addDirectoryList(Args, CmdArgs, "-objc-isystem", "OBJC_INCLUDE_PATH");
566*67e74705SXin Li   // OBJCPLUS_INCLUDE_PATH - system includes enabled when compiling ObjC++.
567*67e74705SXin Li   addDirectoryList(Args, CmdArgs, "-objcxx-isystem", "OBJCPLUS_INCLUDE_PATH");
568*67e74705SXin Li 
569*67e74705SXin Li   // Optional AuxToolChain indicates that we need to include headers
570*67e74705SXin Li   // for more than one target. If that's the case, add include paths
571*67e74705SXin Li   // from AuxToolChain right after include paths of the same kind for
572*67e74705SXin Li   // the current target.
573*67e74705SXin Li 
574*67e74705SXin Li   // Add C++ include arguments, if needed.
575*67e74705SXin Li   if (types::isCXX(Inputs[0].getType())) {
576*67e74705SXin Li     getToolChain().AddClangCXXStdlibIncludeArgs(Args, CmdArgs);
577*67e74705SXin Li     if (AuxToolChain)
578*67e74705SXin Li       AuxToolChain->AddClangCXXStdlibIncludeArgs(Args, CmdArgs);
579*67e74705SXin Li   }
580*67e74705SXin Li 
581*67e74705SXin Li   // Add system include arguments for all targets but IAMCU.
582*67e74705SXin Li   if (!IsIAMCU) {
583*67e74705SXin Li     getToolChain().AddClangSystemIncludeArgs(Args, CmdArgs);
584*67e74705SXin Li     if (AuxToolChain)
585*67e74705SXin Li       AuxToolChain->AddClangCXXStdlibIncludeArgs(Args, CmdArgs);
586*67e74705SXin Li   } else {
587*67e74705SXin Li     // For IAMCU add special include arguments.
588*67e74705SXin Li     getToolChain().AddIAMCUIncludeArgs(Args, CmdArgs);
589*67e74705SXin Li   }
590*67e74705SXin Li 
591*67e74705SXin Li   // Add CUDA include arguments, if needed.
592*67e74705SXin Li   if (types::isCuda(Inputs[0].getType()))
593*67e74705SXin Li     getToolChain().AddCudaIncludeArgs(Args, CmdArgs);
594*67e74705SXin Li }
595*67e74705SXin Li 
596*67e74705SXin Li // FIXME: Move to target hook.
isSignedCharDefault(const llvm::Triple & Triple)597*67e74705SXin Li static bool isSignedCharDefault(const llvm::Triple &Triple) {
598*67e74705SXin Li   switch (Triple.getArch()) {
599*67e74705SXin Li   default:
600*67e74705SXin Li     return true;
601*67e74705SXin Li 
602*67e74705SXin Li   case llvm::Triple::aarch64:
603*67e74705SXin Li   case llvm::Triple::aarch64_be:
604*67e74705SXin Li   case llvm::Triple::arm:
605*67e74705SXin Li   case llvm::Triple::armeb:
606*67e74705SXin Li   case llvm::Triple::thumb:
607*67e74705SXin Li   case llvm::Triple::thumbeb:
608*67e74705SXin Li     if (Triple.isOSDarwin() || Triple.isOSWindows())
609*67e74705SXin Li       return true;
610*67e74705SXin Li     return false;
611*67e74705SXin Li 
612*67e74705SXin Li   case llvm::Triple::ppc:
613*67e74705SXin Li   case llvm::Triple::ppc64:
614*67e74705SXin Li     if (Triple.isOSDarwin())
615*67e74705SXin Li       return true;
616*67e74705SXin Li     return false;
617*67e74705SXin Li 
618*67e74705SXin Li   case llvm::Triple::hexagon:
619*67e74705SXin Li   case llvm::Triple::ppc64le:
620*67e74705SXin Li   case llvm::Triple::systemz:
621*67e74705SXin Li   case llvm::Triple::xcore:
622*67e74705SXin Li     return false;
623*67e74705SXin Li   }
624*67e74705SXin Li }
625*67e74705SXin Li 
isNoCommonDefault(const llvm::Triple & Triple)626*67e74705SXin Li static bool isNoCommonDefault(const llvm::Triple &Triple) {
627*67e74705SXin Li   switch (Triple.getArch()) {
628*67e74705SXin Li   default:
629*67e74705SXin Li     return false;
630*67e74705SXin Li 
631*67e74705SXin Li   case llvm::Triple::xcore:
632*67e74705SXin Li   case llvm::Triple::wasm32:
633*67e74705SXin Li   case llvm::Triple::wasm64:
634*67e74705SXin Li     return true;
635*67e74705SXin Li   }
636*67e74705SXin Li }
637*67e74705SXin Li 
638*67e74705SXin Li // ARM tools start.
639*67e74705SXin Li 
640*67e74705SXin Li // Get SubArch (vN).
getARMSubArchVersionNumber(const llvm::Triple & Triple)641*67e74705SXin Li static int getARMSubArchVersionNumber(const llvm::Triple &Triple) {
642*67e74705SXin Li   llvm::StringRef Arch = Triple.getArchName();
643*67e74705SXin Li   return llvm::ARM::parseArchVersion(Arch);
644*67e74705SXin Li }
645*67e74705SXin Li 
646*67e74705SXin Li // True if M-profile.
isARMMProfile(const llvm::Triple & Triple)647*67e74705SXin Li static bool isARMMProfile(const llvm::Triple &Triple) {
648*67e74705SXin Li   llvm::StringRef Arch = Triple.getArchName();
649*67e74705SXin Li   unsigned Profile = llvm::ARM::parseArchProfile(Arch);
650*67e74705SXin Li   return Profile == llvm::ARM::PK_M;
651*67e74705SXin Li }
652*67e74705SXin Li 
653*67e74705SXin Li // Get Arch/CPU from args.
getARMArchCPUFromArgs(const ArgList & Args,llvm::StringRef & Arch,llvm::StringRef & CPU,bool FromAs=false)654*67e74705SXin Li static void getARMArchCPUFromArgs(const ArgList &Args, llvm::StringRef &Arch,
655*67e74705SXin Li                                   llvm::StringRef &CPU, bool FromAs = false) {
656*67e74705SXin Li   if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
657*67e74705SXin Li     CPU = A->getValue();
658*67e74705SXin Li   if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
659*67e74705SXin Li     Arch = A->getValue();
660*67e74705SXin Li   if (!FromAs)
661*67e74705SXin Li     return;
662*67e74705SXin Li 
663*67e74705SXin Li   for (const Arg *A :
664*67e74705SXin Li        Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) {
665*67e74705SXin Li     StringRef Value = A->getValue();
666*67e74705SXin Li     if (Value.startswith("-mcpu="))
667*67e74705SXin Li       CPU = Value.substr(6);
668*67e74705SXin Li     if (Value.startswith("-march="))
669*67e74705SXin Li       Arch = Value.substr(7);
670*67e74705SXin Li   }
671*67e74705SXin Li }
672*67e74705SXin Li 
673*67e74705SXin Li // Handle -mhwdiv=.
674*67e74705SXin Li // FIXME: Use ARMTargetParser.
getARMHWDivFeatures(const Driver & D,const Arg * A,const ArgList & Args,StringRef HWDiv,std::vector<const char * > & Features)675*67e74705SXin Li static void getARMHWDivFeatures(const Driver &D, const Arg *A,
676*67e74705SXin Li                                 const ArgList &Args, StringRef HWDiv,
677*67e74705SXin Li                                 std::vector<const char *> &Features) {
678*67e74705SXin Li   unsigned HWDivID = llvm::ARM::parseHWDiv(HWDiv);
679*67e74705SXin Li   if (!llvm::ARM::getHWDivFeatures(HWDivID, Features))
680*67e74705SXin Li     D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
681*67e74705SXin Li }
682*67e74705SXin Li 
683*67e74705SXin Li // Handle -mfpu=.
getARMFPUFeatures(const Driver & D,const Arg * A,const ArgList & Args,StringRef FPU,std::vector<const char * > & Features)684*67e74705SXin Li static void getARMFPUFeatures(const Driver &D, const Arg *A,
685*67e74705SXin Li                               const ArgList &Args, StringRef FPU,
686*67e74705SXin Li                               std::vector<const char *> &Features) {
687*67e74705SXin Li   unsigned FPUID = llvm::ARM::parseFPU(FPU);
688*67e74705SXin Li   if (!llvm::ARM::getFPUFeatures(FPUID, Features))
689*67e74705SXin Li     D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
690*67e74705SXin Li }
691*67e74705SXin Li 
692*67e74705SXin Li // Decode ARM features from string like +[no]featureA+[no]featureB+...
DecodeARMFeatures(const Driver & D,StringRef text,std::vector<const char * > & Features)693*67e74705SXin Li static bool DecodeARMFeatures(const Driver &D, StringRef text,
694*67e74705SXin Li                               std::vector<const char *> &Features) {
695*67e74705SXin Li   SmallVector<StringRef, 8> Split;
696*67e74705SXin Li   text.split(Split, StringRef("+"), -1, false);
697*67e74705SXin Li 
698*67e74705SXin Li   for (StringRef Feature : Split) {
699*67e74705SXin Li     const char *FeatureName = llvm::ARM::getArchExtFeature(Feature);
700*67e74705SXin Li     if (FeatureName)
701*67e74705SXin Li       Features.push_back(FeatureName);
702*67e74705SXin Li     else
703*67e74705SXin Li       return false;
704*67e74705SXin Li   }
705*67e74705SXin Li   return true;
706*67e74705SXin Li }
707*67e74705SXin Li 
708*67e74705SXin Li // Check if -march is valid by checking if it can be canonicalised and parsed.
709*67e74705SXin Li // getARMArch is used here instead of just checking the -march value in order
710*67e74705SXin Li // to handle -march=native correctly.
checkARMArchName(const Driver & D,const Arg * A,const ArgList & Args,llvm::StringRef ArchName,std::vector<const char * > & Features,const llvm::Triple & Triple)711*67e74705SXin Li static void checkARMArchName(const Driver &D, const Arg *A, const ArgList &Args,
712*67e74705SXin Li                              llvm::StringRef ArchName,
713*67e74705SXin Li                              std::vector<const char *> &Features,
714*67e74705SXin Li                              const llvm::Triple &Triple) {
715*67e74705SXin Li   std::pair<StringRef, StringRef> Split = ArchName.split("+");
716*67e74705SXin Li 
717*67e74705SXin Li   std::string MArch = arm::getARMArch(ArchName, Triple);
718*67e74705SXin Li   if (llvm::ARM::parseArch(MArch) == llvm::ARM::AK_INVALID ||
719*67e74705SXin Li       (Split.second.size() && !DecodeARMFeatures(D, Split.second, Features)))
720*67e74705SXin Li     D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
721*67e74705SXin Li }
722*67e74705SXin Li 
723*67e74705SXin Li // Check -mcpu=. Needs ArchName to handle -mcpu=generic.
checkARMCPUName(const Driver & D,const Arg * A,const ArgList & Args,llvm::StringRef CPUName,llvm::StringRef ArchName,std::vector<const char * > & Features,const llvm::Triple & Triple)724*67e74705SXin Li static void checkARMCPUName(const Driver &D, const Arg *A, const ArgList &Args,
725*67e74705SXin Li                             llvm::StringRef CPUName, llvm::StringRef ArchName,
726*67e74705SXin Li                             std::vector<const char *> &Features,
727*67e74705SXin Li                             const llvm::Triple &Triple) {
728*67e74705SXin Li   std::pair<StringRef, StringRef> Split = CPUName.split("+");
729*67e74705SXin Li 
730*67e74705SXin Li   std::string CPU = arm::getARMTargetCPU(CPUName, ArchName, Triple);
731*67e74705SXin Li   if (arm::getLLVMArchSuffixForARM(CPU, ArchName, Triple).empty() ||
732*67e74705SXin Li       (Split.second.size() && !DecodeARMFeatures(D, Split.second, Features)))
733*67e74705SXin Li     D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
734*67e74705SXin Li }
735*67e74705SXin Li 
useAAPCSForMachO(const llvm::Triple & T)736*67e74705SXin Li static bool useAAPCSForMachO(const llvm::Triple &T) {
737*67e74705SXin Li   // The backend is hardwired to assume AAPCS for M-class processors, ensure
738*67e74705SXin Li   // the frontend matches that.
739*67e74705SXin Li   return T.getEnvironment() == llvm::Triple::EABI ||
740*67e74705SXin Li          T.getOS() == llvm::Triple::UnknownOS || isARMMProfile(T);
741*67e74705SXin Li }
742*67e74705SXin Li 
743*67e74705SXin Li // Select the float ABI as determined by -msoft-float, -mhard-float, and
744*67e74705SXin Li // -mfloat-abi=.
getARMFloatABI(const ToolChain & TC,const ArgList & Args)745*67e74705SXin Li arm::FloatABI arm::getARMFloatABI(const ToolChain &TC, const ArgList &Args) {
746*67e74705SXin Li   const Driver &D = TC.getDriver();
747*67e74705SXin Li   const llvm::Triple Triple(TC.ComputeEffectiveClangTriple(Args));
748*67e74705SXin Li   auto SubArch = getARMSubArchVersionNumber(Triple);
749*67e74705SXin Li   arm::FloatABI ABI = FloatABI::Invalid;
750*67e74705SXin Li   if (Arg *A =
751*67e74705SXin Li           Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
752*67e74705SXin Li                           options::OPT_mfloat_abi_EQ)) {
753*67e74705SXin Li     if (A->getOption().matches(options::OPT_msoft_float)) {
754*67e74705SXin Li       ABI = FloatABI::Soft;
755*67e74705SXin Li     } else if (A->getOption().matches(options::OPT_mhard_float)) {
756*67e74705SXin Li       ABI = FloatABI::Hard;
757*67e74705SXin Li     } else {
758*67e74705SXin Li       ABI = llvm::StringSwitch<arm::FloatABI>(A->getValue())
759*67e74705SXin Li                 .Case("soft", FloatABI::Soft)
760*67e74705SXin Li                 .Case("softfp", FloatABI::SoftFP)
761*67e74705SXin Li                 .Case("hard", FloatABI::Hard)
762*67e74705SXin Li                 .Default(FloatABI::Invalid);
763*67e74705SXin Li       if (ABI == FloatABI::Invalid && !StringRef(A->getValue()).empty()) {
764*67e74705SXin Li         D.Diag(diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);
765*67e74705SXin Li         ABI = FloatABI::Soft;
766*67e74705SXin Li       }
767*67e74705SXin Li     }
768*67e74705SXin Li 
769*67e74705SXin Li     // It is incorrect to select hard float ABI on MachO platforms if the ABI is
770*67e74705SXin Li     // "apcs-gnu".
771*67e74705SXin Li     if (Triple.isOSBinFormatMachO() && !useAAPCSForMachO(Triple) &&
772*67e74705SXin Li         ABI == FloatABI::Hard) {
773*67e74705SXin Li       D.Diag(diag::err_drv_unsupported_opt_for_target) << A->getAsString(Args)
774*67e74705SXin Li                                                        << Triple.getArchName();
775*67e74705SXin Li     }
776*67e74705SXin Li   }
777*67e74705SXin Li 
778*67e74705SXin Li   // If unspecified, choose the default based on the platform.
779*67e74705SXin Li   if (ABI == FloatABI::Invalid) {
780*67e74705SXin Li     switch (Triple.getOS()) {
781*67e74705SXin Li     case llvm::Triple::Darwin:
782*67e74705SXin Li     case llvm::Triple::MacOSX:
783*67e74705SXin Li     case llvm::Triple::IOS:
784*67e74705SXin Li     case llvm::Triple::TvOS: {
785*67e74705SXin Li       // Darwin defaults to "softfp" for v6 and v7.
786*67e74705SXin Li       ABI = (SubArch == 6 || SubArch == 7) ? FloatABI::SoftFP : FloatABI::Soft;
787*67e74705SXin Li       ABI = Triple.isWatchABI() ? FloatABI::Hard : ABI;
788*67e74705SXin Li       break;
789*67e74705SXin Li     }
790*67e74705SXin Li     case llvm::Triple::WatchOS:
791*67e74705SXin Li       ABI = FloatABI::Hard;
792*67e74705SXin Li       break;
793*67e74705SXin Li 
794*67e74705SXin Li     // FIXME: this is invalid for WindowsCE
795*67e74705SXin Li     case llvm::Triple::Win32:
796*67e74705SXin Li       ABI = FloatABI::Hard;
797*67e74705SXin Li       break;
798*67e74705SXin Li 
799*67e74705SXin Li     case llvm::Triple::FreeBSD:
800*67e74705SXin Li       switch (Triple.getEnvironment()) {
801*67e74705SXin Li       case llvm::Triple::GNUEABIHF:
802*67e74705SXin Li         ABI = FloatABI::Hard;
803*67e74705SXin Li         break;
804*67e74705SXin Li       default:
805*67e74705SXin Li         // FreeBSD defaults to soft float
806*67e74705SXin Li         ABI = FloatABI::Soft;
807*67e74705SXin Li         break;
808*67e74705SXin Li       }
809*67e74705SXin Li       break;
810*67e74705SXin Li 
811*67e74705SXin Li     default:
812*67e74705SXin Li       switch (Triple.getEnvironment()) {
813*67e74705SXin Li       case llvm::Triple::GNUEABIHF:
814*67e74705SXin Li       case llvm::Triple::MuslEABIHF:
815*67e74705SXin Li       case llvm::Triple::EABIHF:
816*67e74705SXin Li         ABI = FloatABI::Hard;
817*67e74705SXin Li         break;
818*67e74705SXin Li       case llvm::Triple::GNUEABI:
819*67e74705SXin Li       case llvm::Triple::MuslEABI:
820*67e74705SXin Li       case llvm::Triple::EABI:
821*67e74705SXin Li         // EABI is always AAPCS, and if it was not marked 'hard', it's softfp
822*67e74705SXin Li         ABI = FloatABI::SoftFP;
823*67e74705SXin Li         break;
824*67e74705SXin Li       case llvm::Triple::Android:
825*67e74705SXin Li         ABI = (SubArch == 7) ? FloatABI::SoftFP : FloatABI::Soft;
826*67e74705SXin Li         break;
827*67e74705SXin Li       default:
828*67e74705SXin Li         // Assume "soft", but warn the user we are guessing.
829*67e74705SXin Li         if (Triple.isOSBinFormatMachO() &&
830*67e74705SXin Li             Triple.getSubArch() == llvm::Triple::ARMSubArch_v7em)
831*67e74705SXin Li           ABI = FloatABI::Hard;
832*67e74705SXin Li         else
833*67e74705SXin Li           ABI = FloatABI::Soft;
834*67e74705SXin Li 
835*67e74705SXin Li         if (Triple.getOS() != llvm::Triple::UnknownOS ||
836*67e74705SXin Li             !Triple.isOSBinFormatMachO())
837*67e74705SXin Li           D.Diag(diag::warn_drv_assuming_mfloat_abi_is) << "soft";
838*67e74705SXin Li         break;
839*67e74705SXin Li       }
840*67e74705SXin Li     }
841*67e74705SXin Li   }
842*67e74705SXin Li 
843*67e74705SXin Li   assert(ABI != FloatABI::Invalid && "must select an ABI");
844*67e74705SXin Li   return ABI;
845*67e74705SXin Li }
846*67e74705SXin Li 
getARMTargetFeatures(const ToolChain & TC,const llvm::Triple & Triple,const ArgList & Args,std::vector<const char * > & Features,bool ForAS)847*67e74705SXin Li static void getARMTargetFeatures(const ToolChain &TC,
848*67e74705SXin Li                                  const llvm::Triple &Triple,
849*67e74705SXin Li                                  const ArgList &Args,
850*67e74705SXin Li                                  std::vector<const char *> &Features,
851*67e74705SXin Li                                  bool ForAS) {
852*67e74705SXin Li   const Driver &D = TC.getDriver();
853*67e74705SXin Li 
854*67e74705SXin Li   bool KernelOrKext =
855*67e74705SXin Li       Args.hasArg(options::OPT_mkernel, options::OPT_fapple_kext);
856*67e74705SXin Li   arm::FloatABI ABI = arm::getARMFloatABI(TC, Args);
857*67e74705SXin Li   const Arg *WaCPU = nullptr, *WaFPU = nullptr;
858*67e74705SXin Li   const Arg *WaHDiv = nullptr, *WaArch = nullptr;
859*67e74705SXin Li 
860*67e74705SXin Li   if (!ForAS) {
861*67e74705SXin Li     // FIXME: Note, this is a hack, the LLVM backend doesn't actually use these
862*67e74705SXin Li     // yet (it uses the -mfloat-abi and -msoft-float options), and it is
863*67e74705SXin Li     // stripped out by the ARM target. We should probably pass this a new
864*67e74705SXin Li     // -target-option, which is handled by the -cc1/-cc1as invocation.
865*67e74705SXin Li     //
866*67e74705SXin Li     // FIXME2:  For consistency, it would be ideal if we set up the target
867*67e74705SXin Li     // machine state the same when using the frontend or the assembler. We don't
868*67e74705SXin Li     // currently do that for the assembler, we pass the options directly to the
869*67e74705SXin Li     // backend and never even instantiate the frontend TargetInfo. If we did,
870*67e74705SXin Li     // and used its handleTargetFeatures hook, then we could ensure the
871*67e74705SXin Li     // assembler and the frontend behave the same.
872*67e74705SXin Li 
873*67e74705SXin Li     // Use software floating point operations?
874*67e74705SXin Li     if (ABI == arm::FloatABI::Soft)
875*67e74705SXin Li       Features.push_back("+soft-float");
876*67e74705SXin Li 
877*67e74705SXin Li     // Use software floating point argument passing?
878*67e74705SXin Li     if (ABI != arm::FloatABI::Hard)
879*67e74705SXin Li       Features.push_back("+soft-float-abi");
880*67e74705SXin Li   } else {
881*67e74705SXin Li     // Here, we make sure that -Wa,-mfpu/cpu/arch/hwdiv will be passed down
882*67e74705SXin Li     // to the assembler correctly.
883*67e74705SXin Li     for (const Arg *A :
884*67e74705SXin Li          Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) {
885*67e74705SXin Li       StringRef Value = A->getValue();
886*67e74705SXin Li       if (Value.startswith("-mfpu=")) {
887*67e74705SXin Li         WaFPU = A;
888*67e74705SXin Li       } else if (Value.startswith("-mcpu=")) {
889*67e74705SXin Li         WaCPU = A;
890*67e74705SXin Li       } else if (Value.startswith("-mhwdiv=")) {
891*67e74705SXin Li         WaHDiv = A;
892*67e74705SXin Li       } else if (Value.startswith("-march=")) {
893*67e74705SXin Li         WaArch = A;
894*67e74705SXin Li       }
895*67e74705SXin Li     }
896*67e74705SXin Li   }
897*67e74705SXin Li 
898*67e74705SXin Li   // Check -march. ClangAs gives preference to -Wa,-march=.
899*67e74705SXin Li   const Arg *ArchArg = Args.getLastArg(options::OPT_march_EQ);
900*67e74705SXin Li   StringRef ArchName;
901*67e74705SXin Li   if (WaArch) {
902*67e74705SXin Li     if (ArchArg)
903*67e74705SXin Li       D.Diag(clang::diag::warn_drv_unused_argument)
904*67e74705SXin Li           << ArchArg->getAsString(Args);
905*67e74705SXin Li     ArchName = StringRef(WaArch->getValue()).substr(7);
906*67e74705SXin Li     checkARMArchName(D, WaArch, Args, ArchName, Features, Triple);
907*67e74705SXin Li     // FIXME: Set Arch.
908*67e74705SXin Li     D.Diag(clang::diag::warn_drv_unused_argument) << WaArch->getAsString(Args);
909*67e74705SXin Li   } else if (ArchArg) {
910*67e74705SXin Li     ArchName = ArchArg->getValue();
911*67e74705SXin Li     checkARMArchName(D, ArchArg, Args, ArchName, Features, Triple);
912*67e74705SXin Li   }
913*67e74705SXin Li 
914*67e74705SXin Li   // Check -mcpu. ClangAs gives preference to -Wa,-mcpu=.
915*67e74705SXin Li   const Arg *CPUArg = Args.getLastArg(options::OPT_mcpu_EQ);
916*67e74705SXin Li   StringRef CPUName;
917*67e74705SXin Li   if (WaCPU) {
918*67e74705SXin Li     if (CPUArg)
919*67e74705SXin Li       D.Diag(clang::diag::warn_drv_unused_argument)
920*67e74705SXin Li           << CPUArg->getAsString(Args);
921*67e74705SXin Li     CPUName = StringRef(WaCPU->getValue()).substr(6);
922*67e74705SXin Li     checkARMCPUName(D, WaCPU, Args, CPUName, ArchName, Features, Triple);
923*67e74705SXin Li   } else if (CPUArg) {
924*67e74705SXin Li     CPUName = CPUArg->getValue();
925*67e74705SXin Li     checkARMCPUName(D, CPUArg, Args, CPUName, ArchName, Features, Triple);
926*67e74705SXin Li   }
927*67e74705SXin Li 
928*67e74705SXin Li   // Add CPU features for generic CPUs
929*67e74705SXin Li   if (CPUName == "native") {
930*67e74705SXin Li     llvm::StringMap<bool> HostFeatures;
931*67e74705SXin Li     if (llvm::sys::getHostCPUFeatures(HostFeatures))
932*67e74705SXin Li       for (auto &F : HostFeatures)
933*67e74705SXin Li         Features.push_back(
934*67e74705SXin Li             Args.MakeArgString((F.second ? "+" : "-") + F.first()));
935*67e74705SXin Li   }
936*67e74705SXin Li 
937*67e74705SXin Li   // Honor -mfpu=. ClangAs gives preference to -Wa,-mfpu=.
938*67e74705SXin Li   const Arg *FPUArg = Args.getLastArg(options::OPT_mfpu_EQ);
939*67e74705SXin Li   if (WaFPU) {
940*67e74705SXin Li     if (FPUArg)
941*67e74705SXin Li       D.Diag(clang::diag::warn_drv_unused_argument)
942*67e74705SXin Li           << FPUArg->getAsString(Args);
943*67e74705SXin Li     getARMFPUFeatures(D, WaFPU, Args, StringRef(WaFPU->getValue()).substr(6),
944*67e74705SXin Li                       Features);
945*67e74705SXin Li   } else if (FPUArg) {
946*67e74705SXin Li     getARMFPUFeatures(D, FPUArg, Args, FPUArg->getValue(), Features);
947*67e74705SXin Li   }
948*67e74705SXin Li 
949*67e74705SXin Li   // Honor -mhwdiv=. ClangAs gives preference to -Wa,-mhwdiv=.
950*67e74705SXin Li   const Arg *HDivArg = Args.getLastArg(options::OPT_mhwdiv_EQ);
951*67e74705SXin Li   if (WaHDiv) {
952*67e74705SXin Li     if (HDivArg)
953*67e74705SXin Li       D.Diag(clang::diag::warn_drv_unused_argument)
954*67e74705SXin Li           << HDivArg->getAsString(Args);
955*67e74705SXin Li     getARMHWDivFeatures(D, WaHDiv, Args,
956*67e74705SXin Li                         StringRef(WaHDiv->getValue()).substr(8), Features);
957*67e74705SXin Li   } else if (HDivArg)
958*67e74705SXin Li     getARMHWDivFeatures(D, HDivArg, Args, HDivArg->getValue(), Features);
959*67e74705SXin Li 
960*67e74705SXin Li   // Setting -msoft-float effectively disables NEON because of the GCC
961*67e74705SXin Li   // implementation, although the same isn't true of VFP or VFP3.
962*67e74705SXin Li   if (ABI == arm::FloatABI::Soft) {
963*67e74705SXin Li     Features.push_back("-neon");
964*67e74705SXin Li     // Also need to explicitly disable features which imply NEON.
965*67e74705SXin Li     Features.push_back("-crypto");
966*67e74705SXin Li   }
967*67e74705SXin Li 
968*67e74705SXin Li   // En/disable crc code generation.
969*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_mcrc, options::OPT_mnocrc)) {
970*67e74705SXin Li     if (A->getOption().matches(options::OPT_mcrc))
971*67e74705SXin Li       Features.push_back("+crc");
972*67e74705SXin Li     else
973*67e74705SXin Li       Features.push_back("-crc");
974*67e74705SXin Li   }
975*67e74705SXin Li 
976*67e74705SXin Li   // Look for the last occurrence of -mlong-calls or -mno-long-calls. If
977*67e74705SXin Li   // neither options are specified, see if we are compiling for kernel/kext and
978*67e74705SXin Li   // decide whether to pass "+long-calls" based on the OS and its version.
979*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_mlong_calls,
980*67e74705SXin Li                                options::OPT_mno_long_calls)) {
981*67e74705SXin Li     if (A->getOption().matches(options::OPT_mlong_calls))
982*67e74705SXin Li       Features.push_back("+long-calls");
983*67e74705SXin Li   } else if (KernelOrKext && (!Triple.isiOS() || Triple.isOSVersionLT(6)) &&
984*67e74705SXin Li              !Triple.isWatchOS()) {
985*67e74705SXin Li       Features.push_back("+long-calls");
986*67e74705SXin Li   }
987*67e74705SXin Li 
988*67e74705SXin Li   // Kernel code has more strict alignment requirements.
989*67e74705SXin Li   if (KernelOrKext)
990*67e74705SXin Li     Features.push_back("+strict-align");
991*67e74705SXin Li   else if (Arg *A = Args.getLastArg(options::OPT_mno_unaligned_access,
992*67e74705SXin Li                                     options::OPT_munaligned_access)) {
993*67e74705SXin Li     if (A->getOption().matches(options::OPT_munaligned_access)) {
994*67e74705SXin Li       // No v6M core supports unaligned memory access (v6M ARM ARM A3.2).
995*67e74705SXin Li       if (Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v6m)
996*67e74705SXin Li         D.Diag(diag::err_target_unsupported_unaligned) << "v6m";
997*67e74705SXin Li       // v8M Baseline follows on from v6M, so doesn't support unaligned memory
998*67e74705SXin Li       // access either.
999*67e74705SXin Li       else if (Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v8m_baseline)
1000*67e74705SXin Li         D.Diag(diag::err_target_unsupported_unaligned) << "v8m.base";
1001*67e74705SXin Li     } else
1002*67e74705SXin Li       Features.push_back("+strict-align");
1003*67e74705SXin Li   } else {
1004*67e74705SXin Li     // Assume pre-ARMv6 doesn't support unaligned accesses.
1005*67e74705SXin Li     //
1006*67e74705SXin Li     // ARMv6 may or may not support unaligned accesses depending on the
1007*67e74705SXin Li     // SCTLR.U bit, which is architecture-specific. We assume ARMv6
1008*67e74705SXin Li     // Darwin and NetBSD targets support unaligned accesses, and others don't.
1009*67e74705SXin Li     //
1010*67e74705SXin Li     // ARMv7 always has SCTLR.U set to 1, but it has a new SCTLR.A bit
1011*67e74705SXin Li     // which raises an alignment fault on unaligned accesses. Linux
1012*67e74705SXin Li     // defaults this bit to 0 and handles it as a system-wide (not
1013*67e74705SXin Li     // per-process) setting. It is therefore safe to assume that ARMv7+
1014*67e74705SXin Li     // Linux targets support unaligned accesses. The same goes for NaCl.
1015*67e74705SXin Li     //
1016*67e74705SXin Li     // The above behavior is consistent with GCC.
1017*67e74705SXin Li     int VersionNum = getARMSubArchVersionNumber(Triple);
1018*67e74705SXin Li     if (Triple.isOSDarwin() || Triple.isOSNetBSD()) {
1019*67e74705SXin Li       if (VersionNum < 6 ||
1020*67e74705SXin Li           Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v6m)
1021*67e74705SXin Li         Features.push_back("+strict-align");
1022*67e74705SXin Li     } else if (Triple.isOSLinux() || Triple.isOSNaCl()) {
1023*67e74705SXin Li       if (VersionNum < 7)
1024*67e74705SXin Li         Features.push_back("+strict-align");
1025*67e74705SXin Li     } else
1026*67e74705SXin Li       Features.push_back("+strict-align");
1027*67e74705SXin Li   }
1028*67e74705SXin Li 
1029*67e74705SXin Li   // llvm does not support reserving registers in general. There is support
1030*67e74705SXin Li   // for reserving r9 on ARM though (defined as a platform-specific register
1031*67e74705SXin Li   // in ARM EABI).
1032*67e74705SXin Li   if (Args.hasArg(options::OPT_ffixed_r9))
1033*67e74705SXin Li     Features.push_back("+reserve-r9");
1034*67e74705SXin Li 
1035*67e74705SXin Li   // The kext linker doesn't know how to deal with movw/movt.
1036*67e74705SXin Li   if (KernelOrKext || Args.hasArg(options::OPT_mno_movt))
1037*67e74705SXin Li     Features.push_back("+no-movt");
1038*67e74705SXin Li }
1039*67e74705SXin Li 
AddARMTargetArgs(const llvm::Triple & Triple,const ArgList & Args,ArgStringList & CmdArgs,bool KernelOrKext) const1040*67e74705SXin Li void Clang::AddARMTargetArgs(const llvm::Triple &Triple, const ArgList &Args,
1041*67e74705SXin Li                              ArgStringList &CmdArgs, bool KernelOrKext) const {
1042*67e74705SXin Li   // Select the ABI to use.
1043*67e74705SXin Li   // FIXME: Support -meabi.
1044*67e74705SXin Li   // FIXME: Parts of this are duplicated in the backend, unify this somehow.
1045*67e74705SXin Li   const char *ABIName = nullptr;
1046*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) {
1047*67e74705SXin Li     ABIName = A->getValue();
1048*67e74705SXin Li   } else if (Triple.isOSBinFormatMachO()) {
1049*67e74705SXin Li     if (useAAPCSForMachO(Triple)) {
1050*67e74705SXin Li       ABIName = "aapcs";
1051*67e74705SXin Li     } else if (Triple.isWatchABI()) {
1052*67e74705SXin Li       ABIName = "aapcs16";
1053*67e74705SXin Li     } else {
1054*67e74705SXin Li       ABIName = "apcs-gnu";
1055*67e74705SXin Li     }
1056*67e74705SXin Li   } else if (Triple.isOSWindows()) {
1057*67e74705SXin Li     // FIXME: this is invalid for WindowsCE
1058*67e74705SXin Li     ABIName = "aapcs";
1059*67e74705SXin Li   } else {
1060*67e74705SXin Li     // Select the default based on the platform.
1061*67e74705SXin Li     switch (Triple.getEnvironment()) {
1062*67e74705SXin Li     case llvm::Triple::Android:
1063*67e74705SXin Li     case llvm::Triple::GNUEABI:
1064*67e74705SXin Li     case llvm::Triple::GNUEABIHF:
1065*67e74705SXin Li     case llvm::Triple::MuslEABI:
1066*67e74705SXin Li     case llvm::Triple::MuslEABIHF:
1067*67e74705SXin Li       ABIName = "aapcs-linux";
1068*67e74705SXin Li       break;
1069*67e74705SXin Li     case llvm::Triple::EABIHF:
1070*67e74705SXin Li     case llvm::Triple::EABI:
1071*67e74705SXin Li       ABIName = "aapcs";
1072*67e74705SXin Li       break;
1073*67e74705SXin Li     default:
1074*67e74705SXin Li       if (Triple.getOS() == llvm::Triple::NetBSD)
1075*67e74705SXin Li         ABIName = "apcs-gnu";
1076*67e74705SXin Li       else
1077*67e74705SXin Li         ABIName = "aapcs";
1078*67e74705SXin Li       break;
1079*67e74705SXin Li     }
1080*67e74705SXin Li   }
1081*67e74705SXin Li   CmdArgs.push_back("-target-abi");
1082*67e74705SXin Li   CmdArgs.push_back(ABIName);
1083*67e74705SXin Li 
1084*67e74705SXin Li   // Determine floating point ABI from the options & target defaults.
1085*67e74705SXin Li   arm::FloatABI ABI = arm::getARMFloatABI(getToolChain(), Args);
1086*67e74705SXin Li   if (ABI == arm::FloatABI::Soft) {
1087*67e74705SXin Li     // Floating point operations and argument passing are soft.
1088*67e74705SXin Li     // FIXME: This changes CPP defines, we need -target-soft-float.
1089*67e74705SXin Li     CmdArgs.push_back("-msoft-float");
1090*67e74705SXin Li     CmdArgs.push_back("-mfloat-abi");
1091*67e74705SXin Li     CmdArgs.push_back("soft");
1092*67e74705SXin Li   } else if (ABI == arm::FloatABI::SoftFP) {
1093*67e74705SXin Li     // Floating point operations are hard, but argument passing is soft.
1094*67e74705SXin Li     CmdArgs.push_back("-mfloat-abi");
1095*67e74705SXin Li     CmdArgs.push_back("soft");
1096*67e74705SXin Li   } else {
1097*67e74705SXin Li     // Floating point operations and argument passing are hard.
1098*67e74705SXin Li     assert(ABI == arm::FloatABI::Hard && "Invalid float abi!");
1099*67e74705SXin Li     CmdArgs.push_back("-mfloat-abi");
1100*67e74705SXin Li     CmdArgs.push_back("hard");
1101*67e74705SXin Li   }
1102*67e74705SXin Li 
1103*67e74705SXin Li   // Forward the -mglobal-merge option for explicit control over the pass.
1104*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_mglobal_merge,
1105*67e74705SXin Li                                options::OPT_mno_global_merge)) {
1106*67e74705SXin Li     CmdArgs.push_back("-backend-option");
1107*67e74705SXin Li     if (A->getOption().matches(options::OPT_mno_global_merge))
1108*67e74705SXin Li       CmdArgs.push_back("-arm-global-merge=false");
1109*67e74705SXin Li     else
1110*67e74705SXin Li       CmdArgs.push_back("-arm-global-merge=true");
1111*67e74705SXin Li   }
1112*67e74705SXin Li 
1113*67e74705SXin Li   if (!Args.hasFlag(options::OPT_mimplicit_float,
1114*67e74705SXin Li                     options::OPT_mno_implicit_float, true))
1115*67e74705SXin Li     CmdArgs.push_back("-no-implicit-float");
1116*67e74705SXin Li }
1117*67e74705SXin Li // ARM tools end.
1118*67e74705SXin Li 
1119*67e74705SXin Li /// getAArch64TargetCPU - Get the (LLVM) name of the AArch64 cpu we are
1120*67e74705SXin Li /// targeting.
getAArch64TargetCPU(const ArgList & Args)1121*67e74705SXin Li static std::string getAArch64TargetCPU(const ArgList &Args) {
1122*67e74705SXin Li   Arg *A;
1123*67e74705SXin Li   std::string CPU;
1124*67e74705SXin Li   // If we have -mtune or -mcpu, use that.
1125*67e74705SXin Li   if ((A = Args.getLastArg(options::OPT_mtune_EQ))) {
1126*67e74705SXin Li     CPU = StringRef(A->getValue()).lower();
1127*67e74705SXin Li   } else if ((A = Args.getLastArg(options::OPT_mcpu_EQ))) {
1128*67e74705SXin Li     StringRef Mcpu = A->getValue();
1129*67e74705SXin Li     CPU = Mcpu.split("+").first.lower();
1130*67e74705SXin Li   }
1131*67e74705SXin Li 
1132*67e74705SXin Li   // Handle CPU name is 'native'.
1133*67e74705SXin Li   if (CPU == "native")
1134*67e74705SXin Li     return llvm::sys::getHostCPUName();
1135*67e74705SXin Li   else if (CPU.size())
1136*67e74705SXin Li     return CPU;
1137*67e74705SXin Li 
1138*67e74705SXin Li   // Make sure we pick "cyclone" if -arch is used.
1139*67e74705SXin Li   // FIXME: Should this be picked by checking the target triple instead?
1140*67e74705SXin Li   if (Args.getLastArg(options::OPT_arch))
1141*67e74705SXin Li     return "cyclone";
1142*67e74705SXin Li 
1143*67e74705SXin Li   return "generic";
1144*67e74705SXin Li }
1145*67e74705SXin Li 
AddAArch64TargetArgs(const ArgList & Args,ArgStringList & CmdArgs) const1146*67e74705SXin Li void Clang::AddAArch64TargetArgs(const ArgList &Args,
1147*67e74705SXin Li                                  ArgStringList &CmdArgs) const {
1148*67e74705SXin Li   std::string TripleStr = getToolChain().ComputeEffectiveClangTriple(Args);
1149*67e74705SXin Li   llvm::Triple Triple(TripleStr);
1150*67e74705SXin Li 
1151*67e74705SXin Li   if (!Args.hasFlag(options::OPT_mred_zone, options::OPT_mno_red_zone, true) ||
1152*67e74705SXin Li       Args.hasArg(options::OPT_mkernel) ||
1153*67e74705SXin Li       Args.hasArg(options::OPT_fapple_kext))
1154*67e74705SXin Li     CmdArgs.push_back("-disable-red-zone");
1155*67e74705SXin Li 
1156*67e74705SXin Li   if (!Args.hasFlag(options::OPT_mimplicit_float,
1157*67e74705SXin Li                     options::OPT_mno_implicit_float, true))
1158*67e74705SXin Li     CmdArgs.push_back("-no-implicit-float");
1159*67e74705SXin Li 
1160*67e74705SXin Li   const char *ABIName = nullptr;
1161*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ))
1162*67e74705SXin Li     ABIName = A->getValue();
1163*67e74705SXin Li   else if (Triple.isOSDarwin())
1164*67e74705SXin Li     ABIName = "darwinpcs";
1165*67e74705SXin Li   else
1166*67e74705SXin Li     ABIName = "aapcs";
1167*67e74705SXin Li 
1168*67e74705SXin Li   CmdArgs.push_back("-target-abi");
1169*67e74705SXin Li   CmdArgs.push_back(ABIName);
1170*67e74705SXin Li 
1171*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_mfix_cortex_a53_835769,
1172*67e74705SXin Li                                options::OPT_mno_fix_cortex_a53_835769)) {
1173*67e74705SXin Li     CmdArgs.push_back("-backend-option");
1174*67e74705SXin Li     if (A->getOption().matches(options::OPT_mfix_cortex_a53_835769))
1175*67e74705SXin Li       CmdArgs.push_back("-aarch64-fix-cortex-a53-835769=1");
1176*67e74705SXin Li     else
1177*67e74705SXin Li       CmdArgs.push_back("-aarch64-fix-cortex-a53-835769=0");
1178*67e74705SXin Li   } else if (Triple.isAndroid()) {
1179*67e74705SXin Li     // Enabled A53 errata (835769) workaround by default on android
1180*67e74705SXin Li     CmdArgs.push_back("-backend-option");
1181*67e74705SXin Li     CmdArgs.push_back("-aarch64-fix-cortex-a53-835769=1");
1182*67e74705SXin Li   }
1183*67e74705SXin Li 
1184*67e74705SXin Li   // Forward the -mglobal-merge option for explicit control over the pass.
1185*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_mglobal_merge,
1186*67e74705SXin Li                                options::OPT_mno_global_merge)) {
1187*67e74705SXin Li     CmdArgs.push_back("-backend-option");
1188*67e74705SXin Li     if (A->getOption().matches(options::OPT_mno_global_merge))
1189*67e74705SXin Li       CmdArgs.push_back("-aarch64-global-merge=false");
1190*67e74705SXin Li     else
1191*67e74705SXin Li       CmdArgs.push_back("-aarch64-global-merge=true");
1192*67e74705SXin Li   }
1193*67e74705SXin Li }
1194*67e74705SXin Li 
1195*67e74705SXin Li // Get CPU and ABI names. They are not independent
1196*67e74705SXin Li // so we have to calculate them together.
getMipsCPUAndABI(const ArgList & Args,const llvm::Triple & Triple,StringRef & CPUName,StringRef & ABIName)1197*67e74705SXin Li void mips::getMipsCPUAndABI(const ArgList &Args, const llvm::Triple &Triple,
1198*67e74705SXin Li                             StringRef &CPUName, StringRef &ABIName) {
1199*67e74705SXin Li   const char *DefMips32CPU = "mips32r2";
1200*67e74705SXin Li   const char *DefMips64CPU = "mips64r2";
1201*67e74705SXin Li 
1202*67e74705SXin Li   // MIPS32r6 is the default for mips(el)?-img-linux-gnu and MIPS64r6 is the
1203*67e74705SXin Li   // default for mips64(el)?-img-linux-gnu.
1204*67e74705SXin Li   if (Triple.getVendor() == llvm::Triple::ImaginationTechnologies &&
1205*67e74705SXin Li       Triple.getEnvironment() == llvm::Triple::GNU) {
1206*67e74705SXin Li     DefMips32CPU = "mips32r6";
1207*67e74705SXin Li     DefMips64CPU = "mips64r6";
1208*67e74705SXin Li   }
1209*67e74705SXin Li 
1210*67e74705SXin Li   // MIPS64r6 is the default for Android MIPS64 (mips64el-linux-android).
1211*67e74705SXin Li   if (Triple.isAndroid()) {
1212*67e74705SXin Li     DefMips32CPU = "mips32";
1213*67e74705SXin Li     DefMips64CPU = "mips64r6";
1214*67e74705SXin Li   }
1215*67e74705SXin Li 
1216*67e74705SXin Li   // MIPS3 is the default for mips64*-unknown-openbsd.
1217*67e74705SXin Li   if (Triple.getOS() == llvm::Triple::OpenBSD)
1218*67e74705SXin Li     DefMips64CPU = "mips3";
1219*67e74705SXin Li 
1220*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_march_EQ, options::OPT_mcpu_EQ))
1221*67e74705SXin Li     CPUName = A->getValue();
1222*67e74705SXin Li 
1223*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) {
1224*67e74705SXin Li     ABIName = A->getValue();
1225*67e74705SXin Li     // Convert a GNU style Mips ABI name to the name
1226*67e74705SXin Li     // accepted by LLVM Mips backend.
1227*67e74705SXin Li     ABIName = llvm::StringSwitch<llvm::StringRef>(ABIName)
1228*67e74705SXin Li                   .Case("32", "o32")
1229*67e74705SXin Li                   .Case("64", "n64")
1230*67e74705SXin Li                   .Default(ABIName);
1231*67e74705SXin Li   }
1232*67e74705SXin Li 
1233*67e74705SXin Li   // Setup default CPU and ABI names.
1234*67e74705SXin Li   if (CPUName.empty() && ABIName.empty()) {
1235*67e74705SXin Li     switch (Triple.getArch()) {
1236*67e74705SXin Li     default:
1237*67e74705SXin Li       llvm_unreachable("Unexpected triple arch name");
1238*67e74705SXin Li     case llvm::Triple::mips:
1239*67e74705SXin Li     case llvm::Triple::mipsel:
1240*67e74705SXin Li       CPUName = DefMips32CPU;
1241*67e74705SXin Li       break;
1242*67e74705SXin Li     case llvm::Triple::mips64:
1243*67e74705SXin Li     case llvm::Triple::mips64el:
1244*67e74705SXin Li       CPUName = DefMips64CPU;
1245*67e74705SXin Li       break;
1246*67e74705SXin Li     }
1247*67e74705SXin Li   }
1248*67e74705SXin Li 
1249*67e74705SXin Li   if (ABIName.empty() &&
1250*67e74705SXin Li       (Triple.getVendor() == llvm::Triple::MipsTechnologies ||
1251*67e74705SXin Li        Triple.getVendor() == llvm::Triple::ImaginationTechnologies)) {
1252*67e74705SXin Li     ABIName = llvm::StringSwitch<const char *>(CPUName)
1253*67e74705SXin Li                   .Case("mips1", "o32")
1254*67e74705SXin Li                   .Case("mips2", "o32")
1255*67e74705SXin Li                   .Case("mips3", "n64")
1256*67e74705SXin Li                   .Case("mips4", "n64")
1257*67e74705SXin Li                   .Case("mips5", "n64")
1258*67e74705SXin Li                   .Case("mips32", "o32")
1259*67e74705SXin Li                   .Case("mips32r2", "o32")
1260*67e74705SXin Li                   .Case("mips32r3", "o32")
1261*67e74705SXin Li                   .Case("mips32r5", "o32")
1262*67e74705SXin Li                   .Case("mips32r6", "o32")
1263*67e74705SXin Li                   .Case("mips64", "n64")
1264*67e74705SXin Li                   .Case("mips64r2", "n64")
1265*67e74705SXin Li                   .Case("mips64r3", "n64")
1266*67e74705SXin Li                   .Case("mips64r5", "n64")
1267*67e74705SXin Li                   .Case("mips64r6", "n64")
1268*67e74705SXin Li                   .Case("octeon", "n64")
1269*67e74705SXin Li                   .Case("p5600", "o32")
1270*67e74705SXin Li                   .Default("");
1271*67e74705SXin Li   }
1272*67e74705SXin Li 
1273*67e74705SXin Li   if (ABIName.empty()) {
1274*67e74705SXin Li     // Deduce ABI name from the target triple.
1275*67e74705SXin Li     if (Triple.getArch() == llvm::Triple::mips ||
1276*67e74705SXin Li         Triple.getArch() == llvm::Triple::mipsel)
1277*67e74705SXin Li       ABIName = "o32";
1278*67e74705SXin Li     else
1279*67e74705SXin Li       ABIName = "n64";
1280*67e74705SXin Li   }
1281*67e74705SXin Li 
1282*67e74705SXin Li   if (CPUName.empty()) {
1283*67e74705SXin Li     // Deduce CPU name from ABI name.
1284*67e74705SXin Li     CPUName = llvm::StringSwitch<const char *>(ABIName)
1285*67e74705SXin Li                   .Case("o32", DefMips32CPU)
1286*67e74705SXin Li                   .Cases("n32", "n64", DefMips64CPU)
1287*67e74705SXin Li                   .Default("");
1288*67e74705SXin Li   }
1289*67e74705SXin Li 
1290*67e74705SXin Li   // FIXME: Warn on inconsistent use of -march and -mabi.
1291*67e74705SXin Li }
1292*67e74705SXin Li 
getMipsABILibSuffix(const ArgList & Args,const llvm::Triple & Triple)1293*67e74705SXin Li std::string mips::getMipsABILibSuffix(const ArgList &Args,
1294*67e74705SXin Li                                       const llvm::Triple &Triple) {
1295*67e74705SXin Li   StringRef CPUName, ABIName;
1296*67e74705SXin Li   tools::mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
1297*67e74705SXin Li   return llvm::StringSwitch<std::string>(ABIName)
1298*67e74705SXin Li       .Case("o32", "")
1299*67e74705SXin Li       .Case("n32", "32")
1300*67e74705SXin Li       .Case("n64", "64");
1301*67e74705SXin Li }
1302*67e74705SXin Li 
1303*67e74705SXin Li // Convert ABI name to the GNU tools acceptable variant.
getGnuCompatibleMipsABIName(StringRef ABI)1304*67e74705SXin Li static StringRef getGnuCompatibleMipsABIName(StringRef ABI) {
1305*67e74705SXin Li   return llvm::StringSwitch<llvm::StringRef>(ABI)
1306*67e74705SXin Li       .Case("o32", "32")
1307*67e74705SXin Li       .Case("n64", "64")
1308*67e74705SXin Li       .Default(ABI);
1309*67e74705SXin Li }
1310*67e74705SXin Li 
1311*67e74705SXin Li // Select the MIPS float ABI as determined by -msoft-float, -mhard-float,
1312*67e74705SXin Li // and -mfloat-abi=.
getMipsFloatABI(const Driver & D,const ArgList & Args)1313*67e74705SXin Li static mips::FloatABI getMipsFloatABI(const Driver &D, const ArgList &Args) {
1314*67e74705SXin Li   mips::FloatABI ABI = mips::FloatABI::Invalid;
1315*67e74705SXin Li   if (Arg *A =
1316*67e74705SXin Li           Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
1317*67e74705SXin Li                           options::OPT_mfloat_abi_EQ)) {
1318*67e74705SXin Li     if (A->getOption().matches(options::OPT_msoft_float))
1319*67e74705SXin Li       ABI = mips::FloatABI::Soft;
1320*67e74705SXin Li     else if (A->getOption().matches(options::OPT_mhard_float))
1321*67e74705SXin Li       ABI = mips::FloatABI::Hard;
1322*67e74705SXin Li     else {
1323*67e74705SXin Li       ABI = llvm::StringSwitch<mips::FloatABI>(A->getValue())
1324*67e74705SXin Li                 .Case("soft", mips::FloatABI::Soft)
1325*67e74705SXin Li                 .Case("hard", mips::FloatABI::Hard)
1326*67e74705SXin Li                 .Default(mips::FloatABI::Invalid);
1327*67e74705SXin Li       if (ABI == mips::FloatABI::Invalid && !StringRef(A->getValue()).empty()) {
1328*67e74705SXin Li         D.Diag(diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);
1329*67e74705SXin Li         ABI = mips::FloatABI::Hard;
1330*67e74705SXin Li       }
1331*67e74705SXin Li     }
1332*67e74705SXin Li   }
1333*67e74705SXin Li 
1334*67e74705SXin Li   // If unspecified, choose the default based on the platform.
1335*67e74705SXin Li   if (ABI == mips::FloatABI::Invalid) {
1336*67e74705SXin Li     // Assume "hard", because it's a default value used by gcc.
1337*67e74705SXin Li     // When we start to recognize specific target MIPS processors,
1338*67e74705SXin Li     // we will be able to select the default more correctly.
1339*67e74705SXin Li     ABI = mips::FloatABI::Hard;
1340*67e74705SXin Li   }
1341*67e74705SXin Li 
1342*67e74705SXin Li   assert(ABI != mips::FloatABI::Invalid && "must select an ABI");
1343*67e74705SXin Li   return ABI;
1344*67e74705SXin Li }
1345*67e74705SXin Li 
AddTargetFeature(const ArgList & Args,std::vector<const char * > & Features,OptSpecifier OnOpt,OptSpecifier OffOpt,StringRef FeatureName)1346*67e74705SXin Li static void AddTargetFeature(const ArgList &Args,
1347*67e74705SXin Li                              std::vector<const char *> &Features,
1348*67e74705SXin Li                              OptSpecifier OnOpt, OptSpecifier OffOpt,
1349*67e74705SXin Li                              StringRef FeatureName) {
1350*67e74705SXin Li   if (Arg *A = Args.getLastArg(OnOpt, OffOpt)) {
1351*67e74705SXin Li     if (A->getOption().matches(OnOpt))
1352*67e74705SXin Li       Features.push_back(Args.MakeArgString("+" + FeatureName));
1353*67e74705SXin Li     else
1354*67e74705SXin Li       Features.push_back(Args.MakeArgString("-" + FeatureName));
1355*67e74705SXin Li   }
1356*67e74705SXin Li }
1357*67e74705SXin Li 
getMIPSTargetFeatures(const Driver & D,const llvm::Triple & Triple,const ArgList & Args,std::vector<const char * > & Features)1358*67e74705SXin Li static void getMIPSTargetFeatures(const Driver &D, const llvm::Triple &Triple,
1359*67e74705SXin Li                                   const ArgList &Args,
1360*67e74705SXin Li                                   std::vector<const char *> &Features) {
1361*67e74705SXin Li   StringRef CPUName;
1362*67e74705SXin Li   StringRef ABIName;
1363*67e74705SXin Li   mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
1364*67e74705SXin Li   ABIName = getGnuCompatibleMipsABIName(ABIName);
1365*67e74705SXin Li 
1366*67e74705SXin Li   AddTargetFeature(Args, Features, options::OPT_mno_abicalls,
1367*67e74705SXin Li                    options::OPT_mabicalls, "noabicalls");
1368*67e74705SXin Li 
1369*67e74705SXin Li   mips::FloatABI FloatABI = getMipsFloatABI(D, Args);
1370*67e74705SXin Li   if (FloatABI == mips::FloatABI::Soft) {
1371*67e74705SXin Li     // FIXME: Note, this is a hack. We need to pass the selected float
1372*67e74705SXin Li     // mode to the MipsTargetInfoBase to define appropriate macros there.
1373*67e74705SXin Li     // Now it is the only method.
1374*67e74705SXin Li     Features.push_back("+soft-float");
1375*67e74705SXin Li   }
1376*67e74705SXin Li 
1377*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_mnan_EQ)) {
1378*67e74705SXin Li     StringRef Val = StringRef(A->getValue());
1379*67e74705SXin Li     if (Val == "2008") {
1380*67e74705SXin Li       if (mips::getSupportedNanEncoding(CPUName) & mips::Nan2008)
1381*67e74705SXin Li         Features.push_back("+nan2008");
1382*67e74705SXin Li       else {
1383*67e74705SXin Li         Features.push_back("-nan2008");
1384*67e74705SXin Li         D.Diag(diag::warn_target_unsupported_nan2008) << CPUName;
1385*67e74705SXin Li       }
1386*67e74705SXin Li     } else if (Val == "legacy") {
1387*67e74705SXin Li       if (mips::getSupportedNanEncoding(CPUName) & mips::NanLegacy)
1388*67e74705SXin Li         Features.push_back("-nan2008");
1389*67e74705SXin Li       else {
1390*67e74705SXin Li         Features.push_back("+nan2008");
1391*67e74705SXin Li         D.Diag(diag::warn_target_unsupported_nanlegacy) << CPUName;
1392*67e74705SXin Li       }
1393*67e74705SXin Li     } else
1394*67e74705SXin Li       D.Diag(diag::err_drv_unsupported_option_argument)
1395*67e74705SXin Li           << A->getOption().getName() << Val;
1396*67e74705SXin Li   }
1397*67e74705SXin Li 
1398*67e74705SXin Li   AddTargetFeature(Args, Features, options::OPT_msingle_float,
1399*67e74705SXin Li                    options::OPT_mdouble_float, "single-float");
1400*67e74705SXin Li   AddTargetFeature(Args, Features, options::OPT_mips16, options::OPT_mno_mips16,
1401*67e74705SXin Li                    "mips16");
1402*67e74705SXin Li   AddTargetFeature(Args, Features, options::OPT_mmicromips,
1403*67e74705SXin Li                    options::OPT_mno_micromips, "micromips");
1404*67e74705SXin Li   AddTargetFeature(Args, Features, options::OPT_mdsp, options::OPT_mno_dsp,
1405*67e74705SXin Li                    "dsp");
1406*67e74705SXin Li   AddTargetFeature(Args, Features, options::OPT_mdspr2, options::OPT_mno_dspr2,
1407*67e74705SXin Li                    "dspr2");
1408*67e74705SXin Li   AddTargetFeature(Args, Features, options::OPT_mmsa, options::OPT_mno_msa,
1409*67e74705SXin Li                    "msa");
1410*67e74705SXin Li 
1411*67e74705SXin Li   // Add the last -mfp32/-mfpxx/-mfp64, if none are given and the ABI is O32
1412*67e74705SXin Li   // pass -mfpxx, or if none are given and fp64a is default, pass fp64 and
1413*67e74705SXin Li   // nooddspreg.
1414*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_mfp32, options::OPT_mfpxx,
1415*67e74705SXin Li                                options::OPT_mfp64)) {
1416*67e74705SXin Li     if (A->getOption().matches(options::OPT_mfp32))
1417*67e74705SXin Li       Features.push_back(Args.MakeArgString("-fp64"));
1418*67e74705SXin Li     else if (A->getOption().matches(options::OPT_mfpxx)) {
1419*67e74705SXin Li       Features.push_back(Args.MakeArgString("+fpxx"));
1420*67e74705SXin Li       Features.push_back(Args.MakeArgString("+nooddspreg"));
1421*67e74705SXin Li     } else
1422*67e74705SXin Li       Features.push_back(Args.MakeArgString("+fp64"));
1423*67e74705SXin Li   } else if (mips::shouldUseFPXX(Args, Triple, CPUName, ABIName, FloatABI)) {
1424*67e74705SXin Li     Features.push_back(Args.MakeArgString("+fpxx"));
1425*67e74705SXin Li     Features.push_back(Args.MakeArgString("+nooddspreg"));
1426*67e74705SXin Li   } else if (mips::isFP64ADefault(Triple, CPUName)) {
1427*67e74705SXin Li     Features.push_back(Args.MakeArgString("+fp64"));
1428*67e74705SXin Li     Features.push_back(Args.MakeArgString("+nooddspreg"));
1429*67e74705SXin Li   }
1430*67e74705SXin Li 
1431*67e74705SXin Li   AddTargetFeature(Args, Features, options::OPT_mno_odd_spreg,
1432*67e74705SXin Li                    options::OPT_modd_spreg, "nooddspreg");
1433*67e74705SXin Li }
1434*67e74705SXin Li 
AddMIPSTargetArgs(const ArgList & Args,ArgStringList & CmdArgs) const1435*67e74705SXin Li void Clang::AddMIPSTargetArgs(const ArgList &Args,
1436*67e74705SXin Li                               ArgStringList &CmdArgs) const {
1437*67e74705SXin Li   const Driver &D = getToolChain().getDriver();
1438*67e74705SXin Li   StringRef CPUName;
1439*67e74705SXin Li   StringRef ABIName;
1440*67e74705SXin Li   const llvm::Triple &Triple = getToolChain().getTriple();
1441*67e74705SXin Li   mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
1442*67e74705SXin Li 
1443*67e74705SXin Li   CmdArgs.push_back("-target-abi");
1444*67e74705SXin Li   CmdArgs.push_back(ABIName.data());
1445*67e74705SXin Li 
1446*67e74705SXin Li   mips::FloatABI ABI = getMipsFloatABI(D, Args);
1447*67e74705SXin Li   if (ABI == mips::FloatABI::Soft) {
1448*67e74705SXin Li     // Floating point operations and argument passing are soft.
1449*67e74705SXin Li     CmdArgs.push_back("-msoft-float");
1450*67e74705SXin Li     CmdArgs.push_back("-mfloat-abi");
1451*67e74705SXin Li     CmdArgs.push_back("soft");
1452*67e74705SXin Li   } else {
1453*67e74705SXin Li     // Floating point operations and argument passing are hard.
1454*67e74705SXin Li     assert(ABI == mips::FloatABI::Hard && "Invalid float abi!");
1455*67e74705SXin Li     CmdArgs.push_back("-mfloat-abi");
1456*67e74705SXin Li     CmdArgs.push_back("hard");
1457*67e74705SXin Li   }
1458*67e74705SXin Li 
1459*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_mxgot, options::OPT_mno_xgot)) {
1460*67e74705SXin Li     if (A->getOption().matches(options::OPT_mxgot)) {
1461*67e74705SXin Li       CmdArgs.push_back("-mllvm");
1462*67e74705SXin Li       CmdArgs.push_back("-mxgot");
1463*67e74705SXin Li     }
1464*67e74705SXin Li   }
1465*67e74705SXin Li 
1466*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_mldc1_sdc1,
1467*67e74705SXin Li                                options::OPT_mno_ldc1_sdc1)) {
1468*67e74705SXin Li     if (A->getOption().matches(options::OPT_mno_ldc1_sdc1)) {
1469*67e74705SXin Li       CmdArgs.push_back("-mllvm");
1470*67e74705SXin Li       CmdArgs.push_back("-mno-ldc1-sdc1");
1471*67e74705SXin Li     }
1472*67e74705SXin Li   }
1473*67e74705SXin Li 
1474*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_mcheck_zero_division,
1475*67e74705SXin Li                                options::OPT_mno_check_zero_division)) {
1476*67e74705SXin Li     if (A->getOption().matches(options::OPT_mno_check_zero_division)) {
1477*67e74705SXin Li       CmdArgs.push_back("-mllvm");
1478*67e74705SXin Li       CmdArgs.push_back("-mno-check-zero-division");
1479*67e74705SXin Li     }
1480*67e74705SXin Li   }
1481*67e74705SXin Li 
1482*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_G)) {
1483*67e74705SXin Li     StringRef v = A->getValue();
1484*67e74705SXin Li     CmdArgs.push_back("-mllvm");
1485*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString("-mips-ssection-threshold=" + v));
1486*67e74705SXin Li     A->claim();
1487*67e74705SXin Li   }
1488*67e74705SXin Li 
1489*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_mcompact_branches_EQ)) {
1490*67e74705SXin Li     StringRef Val = StringRef(A->getValue());
1491*67e74705SXin Li     if (mips::hasCompactBranches(CPUName)) {
1492*67e74705SXin Li       if (Val == "never" || Val == "always" || Val == "optimal") {
1493*67e74705SXin Li         CmdArgs.push_back("-mllvm");
1494*67e74705SXin Li         CmdArgs.push_back(Args.MakeArgString("-mips-compact-branches=" + Val));
1495*67e74705SXin Li       } else
1496*67e74705SXin Li         D.Diag(diag::err_drv_unsupported_option_argument)
1497*67e74705SXin Li             << A->getOption().getName() << Val;
1498*67e74705SXin Li     } else
1499*67e74705SXin Li       D.Diag(diag::warn_target_unsupported_compact_branches) << CPUName;
1500*67e74705SXin Li   }
1501*67e74705SXin Li }
1502*67e74705SXin Li 
1503*67e74705SXin Li /// getPPCTargetCPU - Get the (LLVM) name of the PowerPC cpu we are targeting.
getPPCTargetCPU(const ArgList & Args)1504*67e74705SXin Li static std::string getPPCTargetCPU(const ArgList &Args) {
1505*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
1506*67e74705SXin Li     StringRef CPUName = A->getValue();
1507*67e74705SXin Li 
1508*67e74705SXin Li     if (CPUName == "native") {
1509*67e74705SXin Li       std::string CPU = llvm::sys::getHostCPUName();
1510*67e74705SXin Li       if (!CPU.empty() && CPU != "generic")
1511*67e74705SXin Li         return CPU;
1512*67e74705SXin Li       else
1513*67e74705SXin Li         return "";
1514*67e74705SXin Li     }
1515*67e74705SXin Li 
1516*67e74705SXin Li     return llvm::StringSwitch<const char *>(CPUName)
1517*67e74705SXin Li         .Case("common", "generic")
1518*67e74705SXin Li         .Case("440", "440")
1519*67e74705SXin Li         .Case("440fp", "440")
1520*67e74705SXin Li         .Case("450", "450")
1521*67e74705SXin Li         .Case("601", "601")
1522*67e74705SXin Li         .Case("602", "602")
1523*67e74705SXin Li         .Case("603", "603")
1524*67e74705SXin Li         .Case("603e", "603e")
1525*67e74705SXin Li         .Case("603ev", "603ev")
1526*67e74705SXin Li         .Case("604", "604")
1527*67e74705SXin Li         .Case("604e", "604e")
1528*67e74705SXin Li         .Case("620", "620")
1529*67e74705SXin Li         .Case("630", "pwr3")
1530*67e74705SXin Li         .Case("G3", "g3")
1531*67e74705SXin Li         .Case("7400", "7400")
1532*67e74705SXin Li         .Case("G4", "g4")
1533*67e74705SXin Li         .Case("7450", "7450")
1534*67e74705SXin Li         .Case("G4+", "g4+")
1535*67e74705SXin Li         .Case("750", "750")
1536*67e74705SXin Li         .Case("970", "970")
1537*67e74705SXin Li         .Case("G5", "g5")
1538*67e74705SXin Li         .Case("a2", "a2")
1539*67e74705SXin Li         .Case("a2q", "a2q")
1540*67e74705SXin Li         .Case("e500mc", "e500mc")
1541*67e74705SXin Li         .Case("e5500", "e5500")
1542*67e74705SXin Li         .Case("power3", "pwr3")
1543*67e74705SXin Li         .Case("power4", "pwr4")
1544*67e74705SXin Li         .Case("power5", "pwr5")
1545*67e74705SXin Li         .Case("power5x", "pwr5x")
1546*67e74705SXin Li         .Case("power6", "pwr6")
1547*67e74705SXin Li         .Case("power6x", "pwr6x")
1548*67e74705SXin Li         .Case("power7", "pwr7")
1549*67e74705SXin Li         .Case("power8", "pwr8")
1550*67e74705SXin Li         .Case("power9", "pwr9")
1551*67e74705SXin Li         .Case("pwr3", "pwr3")
1552*67e74705SXin Li         .Case("pwr4", "pwr4")
1553*67e74705SXin Li         .Case("pwr5", "pwr5")
1554*67e74705SXin Li         .Case("pwr5x", "pwr5x")
1555*67e74705SXin Li         .Case("pwr6", "pwr6")
1556*67e74705SXin Li         .Case("pwr6x", "pwr6x")
1557*67e74705SXin Li         .Case("pwr7", "pwr7")
1558*67e74705SXin Li         .Case("pwr8", "pwr8")
1559*67e74705SXin Li         .Case("pwr9", "pwr9")
1560*67e74705SXin Li         .Case("powerpc", "ppc")
1561*67e74705SXin Li         .Case("powerpc64", "ppc64")
1562*67e74705SXin Li         .Case("powerpc64le", "ppc64le")
1563*67e74705SXin Li         .Default("");
1564*67e74705SXin Li   }
1565*67e74705SXin Li 
1566*67e74705SXin Li   return "";
1567*67e74705SXin Li }
1568*67e74705SXin Li 
getPPCTargetFeatures(const Driver & D,const llvm::Triple & Triple,const ArgList & Args,std::vector<const char * > & Features)1569*67e74705SXin Li static void getPPCTargetFeatures(const Driver &D, const llvm::Triple &Triple,
1570*67e74705SXin Li                                  const ArgList &Args,
1571*67e74705SXin Li                                  std::vector<const char *> &Features) {
1572*67e74705SXin Li   handleTargetFeaturesGroup(Args, Features, options::OPT_m_ppc_Features_Group);
1573*67e74705SXin Li 
1574*67e74705SXin Li   ppc::FloatABI FloatABI = ppc::getPPCFloatABI(D, Args);
1575*67e74705SXin Li   if (FloatABI == ppc::FloatABI::Soft &&
1576*67e74705SXin Li       !(Triple.getArch() == llvm::Triple::ppc64 ||
1577*67e74705SXin Li         Triple.getArch() == llvm::Triple::ppc64le))
1578*67e74705SXin Li     Features.push_back("+soft-float");
1579*67e74705SXin Li   else if (FloatABI == ppc::FloatABI::Soft &&
1580*67e74705SXin Li            (Triple.getArch() == llvm::Triple::ppc64 ||
1581*67e74705SXin Li             Triple.getArch() == llvm::Triple::ppc64le))
1582*67e74705SXin Li     D.Diag(diag::err_drv_invalid_mfloat_abi)
1583*67e74705SXin Li         << "soft float is not supported for ppc64";
1584*67e74705SXin Li 
1585*67e74705SXin Li   // Altivec is a bit weird, allow overriding of the Altivec feature here.
1586*67e74705SXin Li   AddTargetFeature(Args, Features, options::OPT_faltivec,
1587*67e74705SXin Li                    options::OPT_fno_altivec, "altivec");
1588*67e74705SXin Li }
1589*67e74705SXin Li 
getPPCFloatABI(const Driver & D,const ArgList & Args)1590*67e74705SXin Li ppc::FloatABI ppc::getPPCFloatABI(const Driver &D, const ArgList &Args) {
1591*67e74705SXin Li   ppc::FloatABI ABI = ppc::FloatABI::Invalid;
1592*67e74705SXin Li   if (Arg *A =
1593*67e74705SXin Li           Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
1594*67e74705SXin Li                           options::OPT_mfloat_abi_EQ)) {
1595*67e74705SXin Li     if (A->getOption().matches(options::OPT_msoft_float))
1596*67e74705SXin Li       ABI = ppc::FloatABI::Soft;
1597*67e74705SXin Li     else if (A->getOption().matches(options::OPT_mhard_float))
1598*67e74705SXin Li       ABI = ppc::FloatABI::Hard;
1599*67e74705SXin Li     else {
1600*67e74705SXin Li       ABI = llvm::StringSwitch<ppc::FloatABI>(A->getValue())
1601*67e74705SXin Li                 .Case("soft", ppc::FloatABI::Soft)
1602*67e74705SXin Li                 .Case("hard", ppc::FloatABI::Hard)
1603*67e74705SXin Li                 .Default(ppc::FloatABI::Invalid);
1604*67e74705SXin Li       if (ABI == ppc::FloatABI::Invalid && !StringRef(A->getValue()).empty()) {
1605*67e74705SXin Li         D.Diag(diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);
1606*67e74705SXin Li         ABI = ppc::FloatABI::Hard;
1607*67e74705SXin Li       }
1608*67e74705SXin Li     }
1609*67e74705SXin Li   }
1610*67e74705SXin Li 
1611*67e74705SXin Li   // If unspecified, choose the default based on the platform.
1612*67e74705SXin Li   if (ABI == ppc::FloatABI::Invalid) {
1613*67e74705SXin Li     ABI = ppc::FloatABI::Hard;
1614*67e74705SXin Li   }
1615*67e74705SXin Li 
1616*67e74705SXin Li   return ABI;
1617*67e74705SXin Li }
1618*67e74705SXin Li 
AddPPCTargetArgs(const ArgList & Args,ArgStringList & CmdArgs) const1619*67e74705SXin Li void Clang::AddPPCTargetArgs(const ArgList &Args,
1620*67e74705SXin Li                              ArgStringList &CmdArgs) const {
1621*67e74705SXin Li   // Select the ABI to use.
1622*67e74705SXin Li   const char *ABIName = nullptr;
1623*67e74705SXin Li   if (getToolChain().getTriple().isOSLinux())
1624*67e74705SXin Li     switch (getToolChain().getArch()) {
1625*67e74705SXin Li     case llvm::Triple::ppc64: {
1626*67e74705SXin Li       // When targeting a processor that supports QPX, or if QPX is
1627*67e74705SXin Li       // specifically enabled, default to using the ABI that supports QPX (so
1628*67e74705SXin Li       // long as it is not specifically disabled).
1629*67e74705SXin Li       bool HasQPX = false;
1630*67e74705SXin Li       if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
1631*67e74705SXin Li         HasQPX = A->getValue() == StringRef("a2q");
1632*67e74705SXin Li       HasQPX = Args.hasFlag(options::OPT_mqpx, options::OPT_mno_qpx, HasQPX);
1633*67e74705SXin Li       if (HasQPX) {
1634*67e74705SXin Li         ABIName = "elfv1-qpx";
1635*67e74705SXin Li         break;
1636*67e74705SXin Li       }
1637*67e74705SXin Li 
1638*67e74705SXin Li       ABIName = "elfv1";
1639*67e74705SXin Li       break;
1640*67e74705SXin Li     }
1641*67e74705SXin Li     case llvm::Triple::ppc64le:
1642*67e74705SXin Li       ABIName = "elfv2";
1643*67e74705SXin Li       break;
1644*67e74705SXin Li     default:
1645*67e74705SXin Li       break;
1646*67e74705SXin Li     }
1647*67e74705SXin Li 
1648*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ))
1649*67e74705SXin Li     // The ppc64 linux abis are all "altivec" abis by default. Accept and ignore
1650*67e74705SXin Li     // the option if given as we don't have backend support for any targets
1651*67e74705SXin Li     // that don't use the altivec abi.
1652*67e74705SXin Li     if (StringRef(A->getValue()) != "altivec")
1653*67e74705SXin Li       ABIName = A->getValue();
1654*67e74705SXin Li 
1655*67e74705SXin Li   ppc::FloatABI FloatABI =
1656*67e74705SXin Li       ppc::getPPCFloatABI(getToolChain().getDriver(), Args);
1657*67e74705SXin Li 
1658*67e74705SXin Li   if (FloatABI == ppc::FloatABI::Soft) {
1659*67e74705SXin Li     // Floating point operations and argument passing are soft.
1660*67e74705SXin Li     CmdArgs.push_back("-msoft-float");
1661*67e74705SXin Li     CmdArgs.push_back("-mfloat-abi");
1662*67e74705SXin Li     CmdArgs.push_back("soft");
1663*67e74705SXin Li   } else {
1664*67e74705SXin Li     // Floating point operations and argument passing are hard.
1665*67e74705SXin Li     assert(FloatABI == ppc::FloatABI::Hard && "Invalid float abi!");
1666*67e74705SXin Li     CmdArgs.push_back("-mfloat-abi");
1667*67e74705SXin Li     CmdArgs.push_back("hard");
1668*67e74705SXin Li   }
1669*67e74705SXin Li 
1670*67e74705SXin Li   if (ABIName) {
1671*67e74705SXin Li     CmdArgs.push_back("-target-abi");
1672*67e74705SXin Li     CmdArgs.push_back(ABIName);
1673*67e74705SXin Li   }
1674*67e74705SXin Li }
1675*67e74705SXin Li 
hasPPCAbiArg(const ArgList & Args,const char * Value)1676*67e74705SXin Li bool ppc::hasPPCAbiArg(const ArgList &Args, const char *Value) {
1677*67e74705SXin Li   Arg *A = Args.getLastArg(options::OPT_mabi_EQ);
1678*67e74705SXin Li   return A && (A->getValue() == StringRef(Value));
1679*67e74705SXin Li }
1680*67e74705SXin Li 
1681*67e74705SXin Li /// Get the (LLVM) name of the R600 gpu we are targeting.
getR600TargetGPU(const ArgList & Args)1682*67e74705SXin Li static std::string getR600TargetGPU(const ArgList &Args) {
1683*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
1684*67e74705SXin Li     const char *GPUName = A->getValue();
1685*67e74705SXin Li     return llvm::StringSwitch<const char *>(GPUName)
1686*67e74705SXin Li         .Cases("rv630", "rv635", "r600")
1687*67e74705SXin Li         .Cases("rv610", "rv620", "rs780", "rs880")
1688*67e74705SXin Li         .Case("rv740", "rv770")
1689*67e74705SXin Li         .Case("palm", "cedar")
1690*67e74705SXin Li         .Cases("sumo", "sumo2", "sumo")
1691*67e74705SXin Li         .Case("hemlock", "cypress")
1692*67e74705SXin Li         .Case("aruba", "cayman")
1693*67e74705SXin Li         .Default(GPUName);
1694*67e74705SXin Li   }
1695*67e74705SXin Li   return "";
1696*67e74705SXin Li }
1697*67e74705SXin Li 
getLanaiTargetCPU(const ArgList & Args)1698*67e74705SXin Li static std::string getLanaiTargetCPU(const ArgList &Args) {
1699*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
1700*67e74705SXin Li     return A->getValue();
1701*67e74705SXin Li   }
1702*67e74705SXin Li   return "";
1703*67e74705SXin Li }
1704*67e74705SXin Li 
getSparcFloatABI(const Driver & D,const ArgList & Args)1705*67e74705SXin Li sparc::FloatABI sparc::getSparcFloatABI(const Driver &D,
1706*67e74705SXin Li                                         const ArgList &Args) {
1707*67e74705SXin Li   sparc::FloatABI ABI = sparc::FloatABI::Invalid;
1708*67e74705SXin Li   if (Arg *A =
1709*67e74705SXin Li           Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
1710*67e74705SXin Li                           options::OPT_mfloat_abi_EQ)) {
1711*67e74705SXin Li     if (A->getOption().matches(options::OPT_msoft_float))
1712*67e74705SXin Li       ABI = sparc::FloatABI::Soft;
1713*67e74705SXin Li     else if (A->getOption().matches(options::OPT_mhard_float))
1714*67e74705SXin Li       ABI = sparc::FloatABI::Hard;
1715*67e74705SXin Li     else {
1716*67e74705SXin Li       ABI = llvm::StringSwitch<sparc::FloatABI>(A->getValue())
1717*67e74705SXin Li                 .Case("soft", sparc::FloatABI::Soft)
1718*67e74705SXin Li                 .Case("hard", sparc::FloatABI::Hard)
1719*67e74705SXin Li                 .Default(sparc::FloatABI::Invalid);
1720*67e74705SXin Li       if (ABI == sparc::FloatABI::Invalid &&
1721*67e74705SXin Li           !StringRef(A->getValue()).empty()) {
1722*67e74705SXin Li         D.Diag(diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);
1723*67e74705SXin Li         ABI = sparc::FloatABI::Hard;
1724*67e74705SXin Li       }
1725*67e74705SXin Li     }
1726*67e74705SXin Li   }
1727*67e74705SXin Li 
1728*67e74705SXin Li   // If unspecified, choose the default based on the platform.
1729*67e74705SXin Li   // Only the hard-float ABI on Sparc is standardized, and it is the
1730*67e74705SXin Li   // default. GCC also supports a nonstandard soft-float ABI mode, also
1731*67e74705SXin Li   // implemented in LLVM. However as this is not standard we set the default
1732*67e74705SXin Li   // to be hard-float.
1733*67e74705SXin Li   if (ABI == sparc::FloatABI::Invalid) {
1734*67e74705SXin Li     ABI = sparc::FloatABI::Hard;
1735*67e74705SXin Li   }
1736*67e74705SXin Li 
1737*67e74705SXin Li   return ABI;
1738*67e74705SXin Li }
1739*67e74705SXin Li 
getSparcTargetFeatures(const Driver & D,const ArgList & Args,std::vector<const char * > & Features)1740*67e74705SXin Li static void getSparcTargetFeatures(const Driver &D, const ArgList &Args,
1741*67e74705SXin Li                                  std::vector<const char *> &Features) {
1742*67e74705SXin Li   sparc::FloatABI FloatABI = sparc::getSparcFloatABI(D, Args);
1743*67e74705SXin Li   if (FloatABI == sparc::FloatABI::Soft)
1744*67e74705SXin Li     Features.push_back("+soft-float");
1745*67e74705SXin Li }
1746*67e74705SXin Li 
AddSparcTargetArgs(const ArgList & Args,ArgStringList & CmdArgs) const1747*67e74705SXin Li void Clang::AddSparcTargetArgs(const ArgList &Args,
1748*67e74705SXin Li                                ArgStringList &CmdArgs) const {
1749*67e74705SXin Li   sparc::FloatABI FloatABI =
1750*67e74705SXin Li       sparc::getSparcFloatABI(getToolChain().getDriver(), Args);
1751*67e74705SXin Li 
1752*67e74705SXin Li   if (FloatABI == sparc::FloatABI::Soft) {
1753*67e74705SXin Li     // Floating point operations and argument passing are soft.
1754*67e74705SXin Li     CmdArgs.push_back("-msoft-float");
1755*67e74705SXin Li     CmdArgs.push_back("-mfloat-abi");
1756*67e74705SXin Li     CmdArgs.push_back("soft");
1757*67e74705SXin Li   } else {
1758*67e74705SXin Li     // Floating point operations and argument passing are hard.
1759*67e74705SXin Li     assert(FloatABI == sparc::FloatABI::Hard && "Invalid float abi!");
1760*67e74705SXin Li     CmdArgs.push_back("-mfloat-abi");
1761*67e74705SXin Li     CmdArgs.push_back("hard");
1762*67e74705SXin Li   }
1763*67e74705SXin Li }
1764*67e74705SXin Li 
AddSystemZTargetArgs(const ArgList & Args,ArgStringList & CmdArgs) const1765*67e74705SXin Li void Clang::AddSystemZTargetArgs(const ArgList &Args,
1766*67e74705SXin Li                                  ArgStringList &CmdArgs) const {
1767*67e74705SXin Li   if (Args.hasFlag(options::OPT_mbackchain, options::OPT_mno_backchain, false))
1768*67e74705SXin Li     CmdArgs.push_back("-mbackchain");
1769*67e74705SXin Li }
1770*67e74705SXin Li 
getSystemZTargetCPU(const ArgList & Args)1771*67e74705SXin Li static const char *getSystemZTargetCPU(const ArgList &Args) {
1772*67e74705SXin Li   if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
1773*67e74705SXin Li     return A->getValue();
1774*67e74705SXin Li   return "z10";
1775*67e74705SXin Li }
1776*67e74705SXin Li 
getSystemZTargetFeatures(const ArgList & Args,std::vector<const char * > & Features)1777*67e74705SXin Li static void getSystemZTargetFeatures(const ArgList &Args,
1778*67e74705SXin Li                                      std::vector<const char *> &Features) {
1779*67e74705SXin Li   // -m(no-)htm overrides use of the transactional-execution facility.
1780*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_mhtm, options::OPT_mno_htm)) {
1781*67e74705SXin Li     if (A->getOption().matches(options::OPT_mhtm))
1782*67e74705SXin Li       Features.push_back("+transactional-execution");
1783*67e74705SXin Li     else
1784*67e74705SXin Li       Features.push_back("-transactional-execution");
1785*67e74705SXin Li   }
1786*67e74705SXin Li   // -m(no-)vx overrides use of the vector facility.
1787*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_mvx, options::OPT_mno_vx)) {
1788*67e74705SXin Li     if (A->getOption().matches(options::OPT_mvx))
1789*67e74705SXin Li       Features.push_back("+vector");
1790*67e74705SXin Li     else
1791*67e74705SXin Li       Features.push_back("-vector");
1792*67e74705SXin Li   }
1793*67e74705SXin Li }
1794*67e74705SXin Li 
getX86TargetCPU(const ArgList & Args,const llvm::Triple & Triple)1795*67e74705SXin Li static const char *getX86TargetCPU(const ArgList &Args,
1796*67e74705SXin Li                                    const llvm::Triple &Triple) {
1797*67e74705SXin Li   if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
1798*67e74705SXin Li     if (StringRef(A->getValue()) != "native") {
1799*67e74705SXin Li       if (Triple.isOSDarwin() && Triple.getArchName() == "x86_64h")
1800*67e74705SXin Li         return "core-avx2";
1801*67e74705SXin Li 
1802*67e74705SXin Li       return A->getValue();
1803*67e74705SXin Li     }
1804*67e74705SXin Li 
1805*67e74705SXin Li     // FIXME: Reject attempts to use -march=native unless the target matches
1806*67e74705SXin Li     // the host.
1807*67e74705SXin Li     //
1808*67e74705SXin Li     // FIXME: We should also incorporate the detected target features for use
1809*67e74705SXin Li     // with -native.
1810*67e74705SXin Li     std::string CPU = llvm::sys::getHostCPUName();
1811*67e74705SXin Li     if (!CPU.empty() && CPU != "generic")
1812*67e74705SXin Li       return Args.MakeArgString(CPU);
1813*67e74705SXin Li   }
1814*67e74705SXin Li 
1815*67e74705SXin Li   if (const Arg *A = Args.getLastArg(options::OPT__SLASH_arch)) {
1816*67e74705SXin Li     // Mapping built by referring to X86TargetInfo::getDefaultFeatures().
1817*67e74705SXin Li     StringRef Arch = A->getValue();
1818*67e74705SXin Li     const char *CPU;
1819*67e74705SXin Li     if (Triple.getArch() == llvm::Triple::x86) {
1820*67e74705SXin Li       CPU = llvm::StringSwitch<const char *>(Arch)
1821*67e74705SXin Li                 .Case("IA32", "i386")
1822*67e74705SXin Li                 .Case("SSE", "pentium3")
1823*67e74705SXin Li                 .Case("SSE2", "pentium4")
1824*67e74705SXin Li                 .Case("AVX", "sandybridge")
1825*67e74705SXin Li                 .Case("AVX2", "haswell")
1826*67e74705SXin Li                 .Default(nullptr);
1827*67e74705SXin Li     } else {
1828*67e74705SXin Li       CPU = llvm::StringSwitch<const char *>(Arch)
1829*67e74705SXin Li                 .Case("AVX", "sandybridge")
1830*67e74705SXin Li                 .Case("AVX2", "haswell")
1831*67e74705SXin Li                 .Default(nullptr);
1832*67e74705SXin Li     }
1833*67e74705SXin Li     if (CPU)
1834*67e74705SXin Li       return CPU;
1835*67e74705SXin Li   }
1836*67e74705SXin Li 
1837*67e74705SXin Li   // Select the default CPU if none was given (or detection failed).
1838*67e74705SXin Li 
1839*67e74705SXin Li   if (Triple.getArch() != llvm::Triple::x86_64 &&
1840*67e74705SXin Li       Triple.getArch() != llvm::Triple::x86)
1841*67e74705SXin Li     return nullptr; // This routine is only handling x86 targets.
1842*67e74705SXin Li 
1843*67e74705SXin Li   bool Is64Bit = Triple.getArch() == llvm::Triple::x86_64;
1844*67e74705SXin Li 
1845*67e74705SXin Li   // FIXME: Need target hooks.
1846*67e74705SXin Li   if (Triple.isOSDarwin()) {
1847*67e74705SXin Li     if (Triple.getArchName() == "x86_64h")
1848*67e74705SXin Li       return "core-avx2";
1849*67e74705SXin Li     return Is64Bit ? "core2" : "yonah";
1850*67e74705SXin Li   }
1851*67e74705SXin Li 
1852*67e74705SXin Li   // Set up default CPU name for PS4 compilers.
1853*67e74705SXin Li   if (Triple.isPS4CPU())
1854*67e74705SXin Li     return "btver2";
1855*67e74705SXin Li 
1856*67e74705SXin Li   // On Android use targets compatible with gcc
1857*67e74705SXin Li   if (Triple.isAndroid())
1858*67e74705SXin Li     return Is64Bit ? "x86-64" : "i686";
1859*67e74705SXin Li 
1860*67e74705SXin Li   // Everything else goes to x86-64 in 64-bit mode.
1861*67e74705SXin Li   if (Is64Bit)
1862*67e74705SXin Li     return "x86-64";
1863*67e74705SXin Li 
1864*67e74705SXin Li   switch (Triple.getOS()) {
1865*67e74705SXin Li   case llvm::Triple::FreeBSD:
1866*67e74705SXin Li   case llvm::Triple::NetBSD:
1867*67e74705SXin Li   case llvm::Triple::OpenBSD:
1868*67e74705SXin Li     return "i486";
1869*67e74705SXin Li   case llvm::Triple::Haiku:
1870*67e74705SXin Li     return "i586";
1871*67e74705SXin Li   case llvm::Triple::Bitrig:
1872*67e74705SXin Li     return "i686";
1873*67e74705SXin Li   default:
1874*67e74705SXin Li     // Fallback to p4.
1875*67e74705SXin Li     return "pentium4";
1876*67e74705SXin Li   }
1877*67e74705SXin Li }
1878*67e74705SXin Li 
1879*67e74705SXin Li /// Get the (LLVM) name of the WebAssembly cpu we are targeting.
getWebAssemblyTargetCPU(const ArgList & Args)1880*67e74705SXin Li static StringRef getWebAssemblyTargetCPU(const ArgList &Args) {
1881*67e74705SXin Li   // If we have -mcpu=, use that.
1882*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
1883*67e74705SXin Li     StringRef CPU = A->getValue();
1884*67e74705SXin Li 
1885*67e74705SXin Li #ifdef __wasm__
1886*67e74705SXin Li     // Handle "native" by examining the host. "native" isn't meaningful when
1887*67e74705SXin Li     // cross compiling, so only support this when the host is also WebAssembly.
1888*67e74705SXin Li     if (CPU == "native")
1889*67e74705SXin Li       return llvm::sys::getHostCPUName();
1890*67e74705SXin Li #endif
1891*67e74705SXin Li 
1892*67e74705SXin Li     return CPU;
1893*67e74705SXin Li   }
1894*67e74705SXin Li 
1895*67e74705SXin Li   return "generic";
1896*67e74705SXin Li }
1897*67e74705SXin Li 
getCPUName(const ArgList & Args,const llvm::Triple & T,bool FromAs=false)1898*67e74705SXin Li static std::string getCPUName(const ArgList &Args, const llvm::Triple &T,
1899*67e74705SXin Li                               bool FromAs = false) {
1900*67e74705SXin Li   switch (T.getArch()) {
1901*67e74705SXin Li   default:
1902*67e74705SXin Li     return "";
1903*67e74705SXin Li 
1904*67e74705SXin Li   case llvm::Triple::aarch64:
1905*67e74705SXin Li   case llvm::Triple::aarch64_be:
1906*67e74705SXin Li     return getAArch64TargetCPU(Args);
1907*67e74705SXin Li 
1908*67e74705SXin Li   case llvm::Triple::arm:
1909*67e74705SXin Li   case llvm::Triple::armeb:
1910*67e74705SXin Li   case llvm::Triple::thumb:
1911*67e74705SXin Li   case llvm::Triple::thumbeb: {
1912*67e74705SXin Li     StringRef MArch, MCPU;
1913*67e74705SXin Li     getARMArchCPUFromArgs(Args, MArch, MCPU, FromAs);
1914*67e74705SXin Li     return arm::getARMTargetCPU(MCPU, MArch, T);
1915*67e74705SXin Li   }
1916*67e74705SXin Li   case llvm::Triple::mips:
1917*67e74705SXin Li   case llvm::Triple::mipsel:
1918*67e74705SXin Li   case llvm::Triple::mips64:
1919*67e74705SXin Li   case llvm::Triple::mips64el: {
1920*67e74705SXin Li     StringRef CPUName;
1921*67e74705SXin Li     StringRef ABIName;
1922*67e74705SXin Li     mips::getMipsCPUAndABI(Args, T, CPUName, ABIName);
1923*67e74705SXin Li     return CPUName;
1924*67e74705SXin Li   }
1925*67e74705SXin Li 
1926*67e74705SXin Li   case llvm::Triple::nvptx:
1927*67e74705SXin Li   case llvm::Triple::nvptx64:
1928*67e74705SXin Li     if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
1929*67e74705SXin Li       return A->getValue();
1930*67e74705SXin Li     return "";
1931*67e74705SXin Li 
1932*67e74705SXin Li   case llvm::Triple::ppc:
1933*67e74705SXin Li   case llvm::Triple::ppc64:
1934*67e74705SXin Li   case llvm::Triple::ppc64le: {
1935*67e74705SXin Li     std::string TargetCPUName = getPPCTargetCPU(Args);
1936*67e74705SXin Li     // LLVM may default to generating code for the native CPU,
1937*67e74705SXin Li     // but, like gcc, we default to a more generic option for
1938*67e74705SXin Li     // each architecture. (except on Darwin)
1939*67e74705SXin Li     if (TargetCPUName.empty() && !T.isOSDarwin()) {
1940*67e74705SXin Li       if (T.getArch() == llvm::Triple::ppc64)
1941*67e74705SXin Li         TargetCPUName = "ppc64";
1942*67e74705SXin Li       else if (T.getArch() == llvm::Triple::ppc64le)
1943*67e74705SXin Li         TargetCPUName = "ppc64le";
1944*67e74705SXin Li       else
1945*67e74705SXin Li         TargetCPUName = "ppc";
1946*67e74705SXin Li     }
1947*67e74705SXin Li     return TargetCPUName;
1948*67e74705SXin Li   }
1949*67e74705SXin Li 
1950*67e74705SXin Li   case llvm::Triple::sparc:
1951*67e74705SXin Li   case llvm::Triple::sparcel:
1952*67e74705SXin Li   case llvm::Triple::sparcv9:
1953*67e74705SXin Li     if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
1954*67e74705SXin Li       return A->getValue();
1955*67e74705SXin Li     return "";
1956*67e74705SXin Li 
1957*67e74705SXin Li   case llvm::Triple::x86:
1958*67e74705SXin Li   case llvm::Triple::x86_64:
1959*67e74705SXin Li     return getX86TargetCPU(Args, T);
1960*67e74705SXin Li 
1961*67e74705SXin Li   case llvm::Triple::hexagon:
1962*67e74705SXin Li     return "hexagon" +
1963*67e74705SXin Li            toolchains::HexagonToolChain::GetTargetCPUVersion(Args).str();
1964*67e74705SXin Li 
1965*67e74705SXin Li   case llvm::Triple::lanai:
1966*67e74705SXin Li     return getLanaiTargetCPU(Args);
1967*67e74705SXin Li 
1968*67e74705SXin Li   case llvm::Triple::systemz:
1969*67e74705SXin Li     return getSystemZTargetCPU(Args);
1970*67e74705SXin Li 
1971*67e74705SXin Li   case llvm::Triple::r600:
1972*67e74705SXin Li   case llvm::Triple::amdgcn:
1973*67e74705SXin Li     return getR600TargetGPU(Args);
1974*67e74705SXin Li 
1975*67e74705SXin Li   case llvm::Triple::wasm32:
1976*67e74705SXin Li   case llvm::Triple::wasm64:
1977*67e74705SXin Li     return getWebAssemblyTargetCPU(Args);
1978*67e74705SXin Li   }
1979*67e74705SXin Li }
1980*67e74705SXin Li 
AddGoldPlugin(const ToolChain & ToolChain,const ArgList & Args,ArgStringList & CmdArgs,bool IsThinLTO)1981*67e74705SXin Li static void AddGoldPlugin(const ToolChain &ToolChain, const ArgList &Args,
1982*67e74705SXin Li                           ArgStringList &CmdArgs, bool IsThinLTO) {
1983*67e74705SXin Li   // Tell the linker to load the plugin. This has to come before AddLinkerInputs
1984*67e74705SXin Li   // as gold requires -plugin to come before any -plugin-opt that -Wl might
1985*67e74705SXin Li   // forward.
1986*67e74705SXin Li   CmdArgs.push_back("-plugin");
1987*67e74705SXin Li   std::string Plugin =
1988*67e74705SXin Li       ToolChain.getDriver().Dir + "/../lib" CLANG_LIBDIR_SUFFIX "/LLVMgold.so";
1989*67e74705SXin Li   CmdArgs.push_back(Args.MakeArgString(Plugin));
1990*67e74705SXin Li 
1991*67e74705SXin Li   // Try to pass driver level flags relevant to LTO code generation down to
1992*67e74705SXin Li   // the plugin.
1993*67e74705SXin Li 
1994*67e74705SXin Li   // Handle flags for selecting CPU variants.
1995*67e74705SXin Li   std::string CPU = getCPUName(Args, ToolChain.getTriple());
1996*67e74705SXin Li   if (!CPU.empty())
1997*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(Twine("-plugin-opt=mcpu=") + CPU));
1998*67e74705SXin Li 
1999*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
2000*67e74705SXin Li     StringRef OOpt;
2001*67e74705SXin Li     if (A->getOption().matches(options::OPT_O4) ||
2002*67e74705SXin Li         A->getOption().matches(options::OPT_Ofast))
2003*67e74705SXin Li       OOpt = "3";
2004*67e74705SXin Li     else if (A->getOption().matches(options::OPT_O))
2005*67e74705SXin Li       OOpt = A->getValue();
2006*67e74705SXin Li     else if (A->getOption().matches(options::OPT_O0))
2007*67e74705SXin Li       OOpt = "0";
2008*67e74705SXin Li     if (!OOpt.empty())
2009*67e74705SXin Li       CmdArgs.push_back(Args.MakeArgString(Twine("-plugin-opt=O") + OOpt));
2010*67e74705SXin Li   }
2011*67e74705SXin Li 
2012*67e74705SXin Li   if (IsThinLTO)
2013*67e74705SXin Li     CmdArgs.push_back("-plugin-opt=thinlto");
2014*67e74705SXin Li 
2015*67e74705SXin Li   // If an explicit debugger tuning argument appeared, pass it along.
2016*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_gTune_Group,
2017*67e74705SXin Li                                options::OPT_ggdbN_Group)) {
2018*67e74705SXin Li     if (A->getOption().matches(options::OPT_glldb))
2019*67e74705SXin Li       CmdArgs.push_back("-plugin-opt=-debugger-tune=lldb");
2020*67e74705SXin Li     else if (A->getOption().matches(options::OPT_gsce))
2021*67e74705SXin Li       CmdArgs.push_back("-plugin-opt=-debugger-tune=sce");
2022*67e74705SXin Li     else
2023*67e74705SXin Li       CmdArgs.push_back("-plugin-opt=-debugger-tune=gdb");
2024*67e74705SXin Li   }
2025*67e74705SXin Li }
2026*67e74705SXin Li 
2027*67e74705SXin Li /// This is a helper function for validating the optional refinement step
2028*67e74705SXin Li /// parameter in reciprocal argument strings. Return false if there is an error
2029*67e74705SXin Li /// parsing the refinement step. Otherwise, return true and set the Position
2030*67e74705SXin Li /// of the refinement step in the input string.
getRefinementStep(StringRef In,const Driver & D,const Arg & A,size_t & Position)2031*67e74705SXin Li static bool getRefinementStep(StringRef In, const Driver &D,
2032*67e74705SXin Li                               const Arg &A, size_t &Position) {
2033*67e74705SXin Li   const char RefinementStepToken = ':';
2034*67e74705SXin Li   Position = In.find(RefinementStepToken);
2035*67e74705SXin Li   if (Position != StringRef::npos) {
2036*67e74705SXin Li     StringRef Option = A.getOption().getName();
2037*67e74705SXin Li     StringRef RefStep = In.substr(Position + 1);
2038*67e74705SXin Li     // Allow exactly one numeric character for the additional refinement
2039*67e74705SXin Li     // step parameter. This is reasonable for all currently-supported
2040*67e74705SXin Li     // operations and architectures because we would expect that a larger value
2041*67e74705SXin Li     // of refinement steps would cause the estimate "optimization" to
2042*67e74705SXin Li     // under-perform the native operation. Also, if the estimate does not
2043*67e74705SXin Li     // converge quickly, it probably will not ever converge, so further
2044*67e74705SXin Li     // refinement steps will not produce a better answer.
2045*67e74705SXin Li     if (RefStep.size() != 1) {
2046*67e74705SXin Li       D.Diag(diag::err_drv_invalid_value) << Option << RefStep;
2047*67e74705SXin Li       return false;
2048*67e74705SXin Li     }
2049*67e74705SXin Li     char RefStepChar = RefStep[0];
2050*67e74705SXin Li     if (RefStepChar < '0' || RefStepChar > '9') {
2051*67e74705SXin Li       D.Diag(diag::err_drv_invalid_value) << Option << RefStep;
2052*67e74705SXin Li       return false;
2053*67e74705SXin Li     }
2054*67e74705SXin Li   }
2055*67e74705SXin Li   return true;
2056*67e74705SXin Li }
2057*67e74705SXin Li 
2058*67e74705SXin Li /// The -mrecip flag requires processing of many optional parameters.
ParseMRecip(const Driver & D,const ArgList & Args,ArgStringList & OutStrings)2059*67e74705SXin Li static void ParseMRecip(const Driver &D, const ArgList &Args,
2060*67e74705SXin Li                         ArgStringList &OutStrings) {
2061*67e74705SXin Li   StringRef DisabledPrefixIn = "!";
2062*67e74705SXin Li   StringRef DisabledPrefixOut = "!";
2063*67e74705SXin Li   StringRef EnabledPrefixOut = "";
2064*67e74705SXin Li   StringRef Out = "-mrecip=";
2065*67e74705SXin Li 
2066*67e74705SXin Li   Arg *A = Args.getLastArg(options::OPT_mrecip, options::OPT_mrecip_EQ);
2067*67e74705SXin Li   if (!A)
2068*67e74705SXin Li     return;
2069*67e74705SXin Li 
2070*67e74705SXin Li   unsigned NumOptions = A->getNumValues();
2071*67e74705SXin Li   if (NumOptions == 0) {
2072*67e74705SXin Li     // No option is the same as "all".
2073*67e74705SXin Li     OutStrings.push_back(Args.MakeArgString(Out + "all"));
2074*67e74705SXin Li     return;
2075*67e74705SXin Li   }
2076*67e74705SXin Li 
2077*67e74705SXin Li   // Pass through "all", "none", or "default" with an optional refinement step.
2078*67e74705SXin Li   if (NumOptions == 1) {
2079*67e74705SXin Li     StringRef Val = A->getValue(0);
2080*67e74705SXin Li     size_t RefStepLoc;
2081*67e74705SXin Li     if (!getRefinementStep(Val, D, *A, RefStepLoc))
2082*67e74705SXin Li       return;
2083*67e74705SXin Li     StringRef ValBase = Val.slice(0, RefStepLoc);
2084*67e74705SXin Li     if (ValBase == "all" || ValBase == "none" || ValBase == "default") {
2085*67e74705SXin Li       OutStrings.push_back(Args.MakeArgString(Out + Val));
2086*67e74705SXin Li       return;
2087*67e74705SXin Li     }
2088*67e74705SXin Li   }
2089*67e74705SXin Li 
2090*67e74705SXin Li   // Each reciprocal type may be enabled or disabled individually.
2091*67e74705SXin Li   // Check each input value for validity, concatenate them all back together,
2092*67e74705SXin Li   // and pass through.
2093*67e74705SXin Li 
2094*67e74705SXin Li   llvm::StringMap<bool> OptionStrings;
2095*67e74705SXin Li   OptionStrings.insert(std::make_pair("divd", false));
2096*67e74705SXin Li   OptionStrings.insert(std::make_pair("divf", false));
2097*67e74705SXin Li   OptionStrings.insert(std::make_pair("vec-divd", false));
2098*67e74705SXin Li   OptionStrings.insert(std::make_pair("vec-divf", false));
2099*67e74705SXin Li   OptionStrings.insert(std::make_pair("sqrtd", false));
2100*67e74705SXin Li   OptionStrings.insert(std::make_pair("sqrtf", false));
2101*67e74705SXin Li   OptionStrings.insert(std::make_pair("vec-sqrtd", false));
2102*67e74705SXin Li   OptionStrings.insert(std::make_pair("vec-sqrtf", false));
2103*67e74705SXin Li 
2104*67e74705SXin Li   for (unsigned i = 0; i != NumOptions; ++i) {
2105*67e74705SXin Li     StringRef Val = A->getValue(i);
2106*67e74705SXin Li 
2107*67e74705SXin Li     bool IsDisabled = Val.startswith(DisabledPrefixIn);
2108*67e74705SXin Li     // Ignore the disablement token for string matching.
2109*67e74705SXin Li     if (IsDisabled)
2110*67e74705SXin Li       Val = Val.substr(1);
2111*67e74705SXin Li 
2112*67e74705SXin Li     size_t RefStep;
2113*67e74705SXin Li     if (!getRefinementStep(Val, D, *A, RefStep))
2114*67e74705SXin Li       return;
2115*67e74705SXin Li 
2116*67e74705SXin Li     StringRef ValBase = Val.slice(0, RefStep);
2117*67e74705SXin Li     llvm::StringMap<bool>::iterator OptionIter = OptionStrings.find(ValBase);
2118*67e74705SXin Li     if (OptionIter == OptionStrings.end()) {
2119*67e74705SXin Li       // Try again specifying float suffix.
2120*67e74705SXin Li       OptionIter = OptionStrings.find(ValBase.str() + 'f');
2121*67e74705SXin Li       if (OptionIter == OptionStrings.end()) {
2122*67e74705SXin Li         // The input name did not match any known option string.
2123*67e74705SXin Li         D.Diag(diag::err_drv_unknown_argument) << Val;
2124*67e74705SXin Li         return;
2125*67e74705SXin Li       }
2126*67e74705SXin Li       // The option was specified without a float or double suffix.
2127*67e74705SXin Li       // Make sure that the double entry was not already specified.
2128*67e74705SXin Li       // The float entry will be checked below.
2129*67e74705SXin Li       if (OptionStrings[ValBase.str() + 'd']) {
2130*67e74705SXin Li         D.Diag(diag::err_drv_invalid_value) << A->getOption().getName() << Val;
2131*67e74705SXin Li         return;
2132*67e74705SXin Li       }
2133*67e74705SXin Li     }
2134*67e74705SXin Li 
2135*67e74705SXin Li     if (OptionIter->second == true) {
2136*67e74705SXin Li       // Duplicate option specified.
2137*67e74705SXin Li       D.Diag(diag::err_drv_invalid_value) << A->getOption().getName() << Val;
2138*67e74705SXin Li       return;
2139*67e74705SXin Li     }
2140*67e74705SXin Li 
2141*67e74705SXin Li     // Mark the matched option as found. Do not allow duplicate specifiers.
2142*67e74705SXin Li     OptionIter->second = true;
2143*67e74705SXin Li 
2144*67e74705SXin Li     // If the precision was not specified, also mark the double entry as found.
2145*67e74705SXin Li     if (ValBase.back() != 'f' && ValBase.back() != 'd')
2146*67e74705SXin Li       OptionStrings[ValBase.str() + 'd'] = true;
2147*67e74705SXin Li 
2148*67e74705SXin Li     // Build the output string.
2149*67e74705SXin Li     StringRef Prefix = IsDisabled ? DisabledPrefixOut : EnabledPrefixOut;
2150*67e74705SXin Li     Out = Args.MakeArgString(Out + Prefix + Val);
2151*67e74705SXin Li     if (i != NumOptions - 1)
2152*67e74705SXin Li       Out = Args.MakeArgString(Out + ",");
2153*67e74705SXin Li   }
2154*67e74705SXin Li 
2155*67e74705SXin Li   OutStrings.push_back(Args.MakeArgString(Out));
2156*67e74705SXin Li }
2157*67e74705SXin Li 
getX86TargetFeatures(const Driver & D,const llvm::Triple & Triple,const ArgList & Args,std::vector<const char * > & Features)2158*67e74705SXin Li static void getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple,
2159*67e74705SXin Li                                  const ArgList &Args,
2160*67e74705SXin Li                                  std::vector<const char *> &Features) {
2161*67e74705SXin Li   // If -march=native, autodetect the feature list.
2162*67e74705SXin Li   if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
2163*67e74705SXin Li     if (StringRef(A->getValue()) == "native") {
2164*67e74705SXin Li       llvm::StringMap<bool> HostFeatures;
2165*67e74705SXin Li       if (llvm::sys::getHostCPUFeatures(HostFeatures))
2166*67e74705SXin Li         for (auto &F : HostFeatures)
2167*67e74705SXin Li           Features.push_back(
2168*67e74705SXin Li               Args.MakeArgString((F.second ? "+" : "-") + F.first()));
2169*67e74705SXin Li     }
2170*67e74705SXin Li   }
2171*67e74705SXin Li 
2172*67e74705SXin Li   if (Triple.getArchName() == "x86_64h") {
2173*67e74705SXin Li     // x86_64h implies quite a few of the more modern subtarget features
2174*67e74705SXin Li     // for Haswell class CPUs, but not all of them. Opt-out of a few.
2175*67e74705SXin Li     Features.push_back("-rdrnd");
2176*67e74705SXin Li     Features.push_back("-aes");
2177*67e74705SXin Li     Features.push_back("-pclmul");
2178*67e74705SXin Li     Features.push_back("-rtm");
2179*67e74705SXin Li     Features.push_back("-hle");
2180*67e74705SXin Li     Features.push_back("-fsgsbase");
2181*67e74705SXin Li   }
2182*67e74705SXin Li 
2183*67e74705SXin Li   const llvm::Triple::ArchType ArchType = Triple.getArch();
2184*67e74705SXin Li   // Add features to be compatible with gcc for Android.
2185*67e74705SXin Li   if (Triple.isAndroid()) {
2186*67e74705SXin Li     if (ArchType == llvm::Triple::x86_64) {
2187*67e74705SXin Li       Features.push_back("+sse4.2");
2188*67e74705SXin Li       Features.push_back("+popcnt");
2189*67e74705SXin Li     } else
2190*67e74705SXin Li       Features.push_back("+ssse3");
2191*67e74705SXin Li   }
2192*67e74705SXin Li 
2193*67e74705SXin Li   // Set features according to the -arch flag on MSVC.
2194*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT__SLASH_arch)) {
2195*67e74705SXin Li     StringRef Arch = A->getValue();
2196*67e74705SXin Li     bool ArchUsed = false;
2197*67e74705SXin Li     // First, look for flags that are shared in x86 and x86-64.
2198*67e74705SXin Li     if (ArchType == llvm::Triple::x86_64 || ArchType == llvm::Triple::x86) {
2199*67e74705SXin Li       if (Arch == "AVX" || Arch == "AVX2") {
2200*67e74705SXin Li         ArchUsed = true;
2201*67e74705SXin Li         Features.push_back(Args.MakeArgString("+" + Arch.lower()));
2202*67e74705SXin Li       }
2203*67e74705SXin Li     }
2204*67e74705SXin Li     // Then, look for x86-specific flags.
2205*67e74705SXin Li     if (ArchType == llvm::Triple::x86) {
2206*67e74705SXin Li       if (Arch == "IA32") {
2207*67e74705SXin Li         ArchUsed = true;
2208*67e74705SXin Li       } else if (Arch == "SSE" || Arch == "SSE2") {
2209*67e74705SXin Li         ArchUsed = true;
2210*67e74705SXin Li         Features.push_back(Args.MakeArgString("+" + Arch.lower()));
2211*67e74705SXin Li       }
2212*67e74705SXin Li     }
2213*67e74705SXin Li     if (!ArchUsed)
2214*67e74705SXin Li       D.Diag(clang::diag::warn_drv_unused_argument) << A->getAsString(Args);
2215*67e74705SXin Li   }
2216*67e74705SXin Li 
2217*67e74705SXin Li   // Now add any that the user explicitly requested on the command line,
2218*67e74705SXin Li   // which may override the defaults.
2219*67e74705SXin Li   handleTargetFeaturesGroup(Args, Features, options::OPT_m_x86_Features_Group);
2220*67e74705SXin Li }
2221*67e74705SXin Li 
AddX86TargetArgs(const ArgList & Args,ArgStringList & CmdArgs) const2222*67e74705SXin Li void Clang::AddX86TargetArgs(const ArgList &Args,
2223*67e74705SXin Li                              ArgStringList &CmdArgs) const {
2224*67e74705SXin Li   if (!Args.hasFlag(options::OPT_mred_zone, options::OPT_mno_red_zone, true) ||
2225*67e74705SXin Li       Args.hasArg(options::OPT_mkernel) ||
2226*67e74705SXin Li       Args.hasArg(options::OPT_fapple_kext))
2227*67e74705SXin Li     CmdArgs.push_back("-disable-red-zone");
2228*67e74705SXin Li 
2229*67e74705SXin Li   // Default to avoid implicit floating-point for kernel/kext code, but allow
2230*67e74705SXin Li   // that to be overridden with -mno-soft-float.
2231*67e74705SXin Li   bool NoImplicitFloat = (Args.hasArg(options::OPT_mkernel) ||
2232*67e74705SXin Li                           Args.hasArg(options::OPT_fapple_kext));
2233*67e74705SXin Li   if (Arg *A = Args.getLastArg(
2234*67e74705SXin Li           options::OPT_msoft_float, options::OPT_mno_soft_float,
2235*67e74705SXin Li           options::OPT_mimplicit_float, options::OPT_mno_implicit_float)) {
2236*67e74705SXin Li     const Option &O = A->getOption();
2237*67e74705SXin Li     NoImplicitFloat = (O.matches(options::OPT_mno_implicit_float) ||
2238*67e74705SXin Li                        O.matches(options::OPT_msoft_float));
2239*67e74705SXin Li   }
2240*67e74705SXin Li   if (NoImplicitFloat)
2241*67e74705SXin Li     CmdArgs.push_back("-no-implicit-float");
2242*67e74705SXin Li 
2243*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_masm_EQ)) {
2244*67e74705SXin Li     StringRef Value = A->getValue();
2245*67e74705SXin Li     if (Value == "intel" || Value == "att") {
2246*67e74705SXin Li       CmdArgs.push_back("-mllvm");
2247*67e74705SXin Li       CmdArgs.push_back(Args.MakeArgString("-x86-asm-syntax=" + Value));
2248*67e74705SXin Li     } else {
2249*67e74705SXin Li       getToolChain().getDriver().Diag(diag::err_drv_unsupported_option_argument)
2250*67e74705SXin Li           << A->getOption().getName() << Value;
2251*67e74705SXin Li     }
2252*67e74705SXin Li   }
2253*67e74705SXin Li 
2254*67e74705SXin Li   // Set flags to support MCU ABI.
2255*67e74705SXin Li   if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu, false)) {
2256*67e74705SXin Li     CmdArgs.push_back("-mfloat-abi");
2257*67e74705SXin Li     CmdArgs.push_back("soft");
2258*67e74705SXin Li     CmdArgs.push_back("-mstack-alignment=4");
2259*67e74705SXin Li   }
2260*67e74705SXin Li }
2261*67e74705SXin Li 
AddHexagonTargetArgs(const ArgList & Args,ArgStringList & CmdArgs) const2262*67e74705SXin Li void Clang::AddHexagonTargetArgs(const ArgList &Args,
2263*67e74705SXin Li                                  ArgStringList &CmdArgs) const {
2264*67e74705SXin Li   CmdArgs.push_back("-mqdsp6-compat");
2265*67e74705SXin Li   CmdArgs.push_back("-Wreturn-type");
2266*67e74705SXin Li 
2267*67e74705SXin Li   if (auto G = toolchains::HexagonToolChain::getSmallDataThreshold(Args)) {
2268*67e74705SXin Li     std::string N = llvm::utostr(G.getValue());
2269*67e74705SXin Li     std::string Opt = std::string("-hexagon-small-data-threshold=") + N;
2270*67e74705SXin Li     CmdArgs.push_back("-mllvm");
2271*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(Opt));
2272*67e74705SXin Li   }
2273*67e74705SXin Li 
2274*67e74705SXin Li   if (!Args.hasArg(options::OPT_fno_short_enums))
2275*67e74705SXin Li     CmdArgs.push_back("-fshort-enums");
2276*67e74705SXin Li   if (Args.getLastArg(options::OPT_mieee_rnd_near)) {
2277*67e74705SXin Li     CmdArgs.push_back("-mllvm");
2278*67e74705SXin Li     CmdArgs.push_back("-enable-hexagon-ieee-rnd-near");
2279*67e74705SXin Li   }
2280*67e74705SXin Li   CmdArgs.push_back("-mllvm");
2281*67e74705SXin Li   CmdArgs.push_back("-machine-sink-split=0");
2282*67e74705SXin Li }
2283*67e74705SXin Li 
AddLanaiTargetArgs(const ArgList & Args,ArgStringList & CmdArgs) const2284*67e74705SXin Li void Clang::AddLanaiTargetArgs(const ArgList &Args,
2285*67e74705SXin Li                                ArgStringList &CmdArgs) const {
2286*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
2287*67e74705SXin Li     StringRef CPUName = A->getValue();
2288*67e74705SXin Li 
2289*67e74705SXin Li     CmdArgs.push_back("-target-cpu");
2290*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(CPUName));
2291*67e74705SXin Li   }
2292*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_mregparm_EQ)) {
2293*67e74705SXin Li     StringRef Value = A->getValue();
2294*67e74705SXin Li     // Only support mregparm=4 to support old usage. Report error for all other
2295*67e74705SXin Li     // cases.
2296*67e74705SXin Li     int Mregparm;
2297*67e74705SXin Li     if (Value.getAsInteger(10, Mregparm)) {
2298*67e74705SXin Li       if (Mregparm != 4) {
2299*67e74705SXin Li         getToolChain().getDriver().Diag(
2300*67e74705SXin Li             diag::err_drv_unsupported_option_argument)
2301*67e74705SXin Li             << A->getOption().getName() << Value;
2302*67e74705SXin Li       }
2303*67e74705SXin Li     }
2304*67e74705SXin Li   }
2305*67e74705SXin Li }
2306*67e74705SXin Li 
AddWebAssemblyTargetArgs(const ArgList & Args,ArgStringList & CmdArgs) const2307*67e74705SXin Li void Clang::AddWebAssemblyTargetArgs(const ArgList &Args,
2308*67e74705SXin Li                                      ArgStringList &CmdArgs) const {
2309*67e74705SXin Li   // Default to "hidden" visibility.
2310*67e74705SXin Li   if (!Args.hasArg(options::OPT_fvisibility_EQ,
2311*67e74705SXin Li                    options::OPT_fvisibility_ms_compat)) {
2312*67e74705SXin Li     CmdArgs.push_back("-fvisibility");
2313*67e74705SXin Li     CmdArgs.push_back("hidden");
2314*67e74705SXin Li   }
2315*67e74705SXin Li }
2316*67e74705SXin Li 
2317*67e74705SXin Li // Decode AArch64 features from string like +[no]featureA+[no]featureB+...
DecodeAArch64Features(const Driver & D,StringRef text,std::vector<const char * > & Features)2318*67e74705SXin Li static bool DecodeAArch64Features(const Driver &D, StringRef text,
2319*67e74705SXin Li                                   std::vector<const char *> &Features) {
2320*67e74705SXin Li   SmallVector<StringRef, 8> Split;
2321*67e74705SXin Li   text.split(Split, StringRef("+"), -1, false);
2322*67e74705SXin Li 
2323*67e74705SXin Li   for (StringRef Feature : Split) {
2324*67e74705SXin Li     const char *result = llvm::StringSwitch<const char *>(Feature)
2325*67e74705SXin Li                              .Case("fp", "+fp-armv8")
2326*67e74705SXin Li                              .Case("simd", "+neon")
2327*67e74705SXin Li                              .Case("crc", "+crc")
2328*67e74705SXin Li                              .Case("crypto", "+crypto")
2329*67e74705SXin Li                              .Case("fp16", "+fullfp16")
2330*67e74705SXin Li                              .Case("profile", "+spe")
2331*67e74705SXin Li                              .Case("ras", "+ras")
2332*67e74705SXin Li                              .Case("nofp", "-fp-armv8")
2333*67e74705SXin Li                              .Case("nosimd", "-neon")
2334*67e74705SXin Li                              .Case("nocrc", "-crc")
2335*67e74705SXin Li                              .Case("nocrypto", "-crypto")
2336*67e74705SXin Li                              .Case("nofp16", "-fullfp16")
2337*67e74705SXin Li                              .Case("noprofile", "-spe")
2338*67e74705SXin Li                              .Case("noras", "-ras")
2339*67e74705SXin Li                              .Default(nullptr);
2340*67e74705SXin Li     if (result)
2341*67e74705SXin Li       Features.push_back(result);
2342*67e74705SXin Li     else if (Feature == "neon" || Feature == "noneon")
2343*67e74705SXin Li       D.Diag(diag::err_drv_no_neon_modifier);
2344*67e74705SXin Li     else
2345*67e74705SXin Li       return false;
2346*67e74705SXin Li   }
2347*67e74705SXin Li   return true;
2348*67e74705SXin Li }
2349*67e74705SXin Li 
2350*67e74705SXin Li // Check if the CPU name and feature modifiers in -mcpu are legal. If yes,
2351*67e74705SXin Li // decode CPU and feature.
DecodeAArch64Mcpu(const Driver & D,StringRef Mcpu,StringRef & CPU,std::vector<const char * > & Features)2352*67e74705SXin Li static bool DecodeAArch64Mcpu(const Driver &D, StringRef Mcpu, StringRef &CPU,
2353*67e74705SXin Li                               std::vector<const char *> &Features) {
2354*67e74705SXin Li   std::pair<StringRef, StringRef> Split = Mcpu.split("+");
2355*67e74705SXin Li   CPU = Split.first;
2356*67e74705SXin Li   if (CPU == "cortex-a53" || CPU == "cortex-a57" ||
2357*67e74705SXin Li       CPU == "cortex-a72" || CPU == "cortex-a35" || CPU == "exynos-m1" ||
2358*67e74705SXin Li       CPU == "kryo"       || CPU == "cortex-a73" || CPU == "vulcan") {
2359*67e74705SXin Li     Features.push_back("+neon");
2360*67e74705SXin Li     Features.push_back("+crc");
2361*67e74705SXin Li     Features.push_back("+crypto");
2362*67e74705SXin Li   } else if (CPU == "cyclone") {
2363*67e74705SXin Li     Features.push_back("+neon");
2364*67e74705SXin Li     Features.push_back("+crypto");
2365*67e74705SXin Li   } else if (CPU == "generic") {
2366*67e74705SXin Li     Features.push_back("+neon");
2367*67e74705SXin Li   } else {
2368*67e74705SXin Li     return false;
2369*67e74705SXin Li   }
2370*67e74705SXin Li 
2371*67e74705SXin Li   if (Split.second.size() && !DecodeAArch64Features(D, Split.second, Features))
2372*67e74705SXin Li     return false;
2373*67e74705SXin Li 
2374*67e74705SXin Li   return true;
2375*67e74705SXin Li }
2376*67e74705SXin Li 
2377*67e74705SXin Li static bool
getAArch64ArchFeaturesFromMarch(const Driver & D,StringRef March,const ArgList & Args,std::vector<const char * > & Features)2378*67e74705SXin Li getAArch64ArchFeaturesFromMarch(const Driver &D, StringRef March,
2379*67e74705SXin Li                                 const ArgList &Args,
2380*67e74705SXin Li                                 std::vector<const char *> &Features) {
2381*67e74705SXin Li   std::string MarchLowerCase = March.lower();
2382*67e74705SXin Li   std::pair<StringRef, StringRef> Split = StringRef(MarchLowerCase).split("+");
2383*67e74705SXin Li 
2384*67e74705SXin Li   if (Split.first == "armv8-a" || Split.first == "armv8a") {
2385*67e74705SXin Li     // ok, no additional features.
2386*67e74705SXin Li   } else if (Split.first == "armv8.1-a" || Split.first == "armv8.1a") {
2387*67e74705SXin Li     Features.push_back("+v8.1a");
2388*67e74705SXin Li   } else if (Split.first == "armv8.2-a" || Split.first == "armv8.2a" ) {
2389*67e74705SXin Li     Features.push_back("+v8.2a");
2390*67e74705SXin Li   } else {
2391*67e74705SXin Li     return false;
2392*67e74705SXin Li   }
2393*67e74705SXin Li 
2394*67e74705SXin Li   if (Split.second.size() && !DecodeAArch64Features(D, Split.second, Features))
2395*67e74705SXin Li     return false;
2396*67e74705SXin Li 
2397*67e74705SXin Li   return true;
2398*67e74705SXin Li }
2399*67e74705SXin Li 
2400*67e74705SXin Li static bool
getAArch64ArchFeaturesFromMcpu(const Driver & D,StringRef Mcpu,const ArgList & Args,std::vector<const char * > & Features)2401*67e74705SXin Li getAArch64ArchFeaturesFromMcpu(const Driver &D, StringRef Mcpu,
2402*67e74705SXin Li                                const ArgList &Args,
2403*67e74705SXin Li                                std::vector<const char *> &Features) {
2404*67e74705SXin Li   StringRef CPU;
2405*67e74705SXin Li   std::string McpuLowerCase = Mcpu.lower();
2406*67e74705SXin Li   if (!DecodeAArch64Mcpu(D, McpuLowerCase, CPU, Features))
2407*67e74705SXin Li     return false;
2408*67e74705SXin Li 
2409*67e74705SXin Li   return true;
2410*67e74705SXin Li }
2411*67e74705SXin Li 
2412*67e74705SXin Li static bool
getAArch64MicroArchFeaturesFromMtune(const Driver & D,StringRef Mtune,const ArgList & Args,std::vector<const char * > & Features)2413*67e74705SXin Li getAArch64MicroArchFeaturesFromMtune(const Driver &D, StringRef Mtune,
2414*67e74705SXin Li                                      const ArgList &Args,
2415*67e74705SXin Li                                      std::vector<const char *> &Features) {
2416*67e74705SXin Li   std::string MtuneLowerCase = Mtune.lower();
2417*67e74705SXin Li   // Handle CPU name is 'native'.
2418*67e74705SXin Li   if (MtuneLowerCase == "native")
2419*67e74705SXin Li     MtuneLowerCase = llvm::sys::getHostCPUName();
2420*67e74705SXin Li   if (MtuneLowerCase == "cyclone") {
2421*67e74705SXin Li     Features.push_back("+zcm");
2422*67e74705SXin Li     Features.push_back("+zcz");
2423*67e74705SXin Li   }
2424*67e74705SXin Li   return true;
2425*67e74705SXin Li }
2426*67e74705SXin Li 
2427*67e74705SXin Li static bool
getAArch64MicroArchFeaturesFromMcpu(const Driver & D,StringRef Mcpu,const ArgList & Args,std::vector<const char * > & Features)2428*67e74705SXin Li getAArch64MicroArchFeaturesFromMcpu(const Driver &D, StringRef Mcpu,
2429*67e74705SXin Li                                     const ArgList &Args,
2430*67e74705SXin Li                                     std::vector<const char *> &Features) {
2431*67e74705SXin Li   StringRef CPU;
2432*67e74705SXin Li   std::vector<const char *> DecodedFeature;
2433*67e74705SXin Li   std::string McpuLowerCase = Mcpu.lower();
2434*67e74705SXin Li   if (!DecodeAArch64Mcpu(D, McpuLowerCase, CPU, DecodedFeature))
2435*67e74705SXin Li     return false;
2436*67e74705SXin Li 
2437*67e74705SXin Li   return getAArch64MicroArchFeaturesFromMtune(D, CPU, Args, Features);
2438*67e74705SXin Li }
2439*67e74705SXin Li 
getAArch64TargetFeatures(const Driver & D,const ArgList & Args,std::vector<const char * > & Features)2440*67e74705SXin Li static void getAArch64TargetFeatures(const Driver &D, const ArgList &Args,
2441*67e74705SXin Li                                      std::vector<const char *> &Features) {
2442*67e74705SXin Li   Arg *A;
2443*67e74705SXin Li   bool success = true;
2444*67e74705SXin Li   // Enable NEON by default.
2445*67e74705SXin Li   Features.push_back("+neon");
2446*67e74705SXin Li   if ((A = Args.getLastArg(options::OPT_march_EQ)))
2447*67e74705SXin Li     success = getAArch64ArchFeaturesFromMarch(D, A->getValue(), Args, Features);
2448*67e74705SXin Li   else if ((A = Args.getLastArg(options::OPT_mcpu_EQ)))
2449*67e74705SXin Li     success = getAArch64ArchFeaturesFromMcpu(D, A->getValue(), Args, Features);
2450*67e74705SXin Li   else if (Args.hasArg(options::OPT_arch))
2451*67e74705SXin Li     success = getAArch64ArchFeaturesFromMcpu(D, getAArch64TargetCPU(Args), Args,
2452*67e74705SXin Li                                              Features);
2453*67e74705SXin Li 
2454*67e74705SXin Li   if (success && (A = Args.getLastArg(options::OPT_mtune_EQ)))
2455*67e74705SXin Li     success =
2456*67e74705SXin Li         getAArch64MicroArchFeaturesFromMtune(D, A->getValue(), Args, Features);
2457*67e74705SXin Li   else if (success && (A = Args.getLastArg(options::OPT_mcpu_EQ)))
2458*67e74705SXin Li     success =
2459*67e74705SXin Li         getAArch64MicroArchFeaturesFromMcpu(D, A->getValue(), Args, Features);
2460*67e74705SXin Li   else if (Args.hasArg(options::OPT_arch))
2461*67e74705SXin Li     success = getAArch64MicroArchFeaturesFromMcpu(D, getAArch64TargetCPU(Args),
2462*67e74705SXin Li                                                   Args, Features);
2463*67e74705SXin Li 
2464*67e74705SXin Li   if (!success)
2465*67e74705SXin Li     D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
2466*67e74705SXin Li 
2467*67e74705SXin Li   if (Args.getLastArg(options::OPT_mgeneral_regs_only)) {
2468*67e74705SXin Li     Features.push_back("-fp-armv8");
2469*67e74705SXin Li     Features.push_back("-crypto");
2470*67e74705SXin Li     Features.push_back("-neon");
2471*67e74705SXin Li   }
2472*67e74705SXin Li 
2473*67e74705SXin Li   // En/disable crc
2474*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_mcrc, options::OPT_mnocrc)) {
2475*67e74705SXin Li     if (A->getOption().matches(options::OPT_mcrc))
2476*67e74705SXin Li       Features.push_back("+crc");
2477*67e74705SXin Li     else
2478*67e74705SXin Li       Features.push_back("-crc");
2479*67e74705SXin Li   }
2480*67e74705SXin Li 
2481*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_mno_unaligned_access,
2482*67e74705SXin Li                                options::OPT_munaligned_access))
2483*67e74705SXin Li     if (A->getOption().matches(options::OPT_mno_unaligned_access))
2484*67e74705SXin Li       Features.push_back("+strict-align");
2485*67e74705SXin Li 
2486*67e74705SXin Li   if (Args.hasArg(options::OPT_ffixed_x18))
2487*67e74705SXin Li     Features.push_back("+reserve-x18");
2488*67e74705SXin Li }
2489*67e74705SXin Li 
getHexagonTargetFeatures(const ArgList & Args,std::vector<const char * > & Features)2490*67e74705SXin Li static void getHexagonTargetFeatures(const ArgList &Args,
2491*67e74705SXin Li                                      std::vector<const char *> &Features) {
2492*67e74705SXin Li   bool HasHVX = false, HasHVXD = false;
2493*67e74705SXin Li 
2494*67e74705SXin Li   // FIXME: This should be able to use handleTargetFeaturesGroup except it is
2495*67e74705SXin Li   // doing dependent option handling here rather than in initFeatureMap or a
2496*67e74705SXin Li   // similar handler.
2497*67e74705SXin Li   for (auto &A : Args) {
2498*67e74705SXin Li     auto &Opt = A->getOption();
2499*67e74705SXin Li     if (Opt.matches(options::OPT_mhexagon_hvx))
2500*67e74705SXin Li       HasHVX = true;
2501*67e74705SXin Li     else if (Opt.matches(options::OPT_mno_hexagon_hvx))
2502*67e74705SXin Li       HasHVXD = HasHVX = false;
2503*67e74705SXin Li     else if (Opt.matches(options::OPT_mhexagon_hvx_double))
2504*67e74705SXin Li       HasHVXD = HasHVX = true;
2505*67e74705SXin Li     else if (Opt.matches(options::OPT_mno_hexagon_hvx_double))
2506*67e74705SXin Li       HasHVXD = false;
2507*67e74705SXin Li     else
2508*67e74705SXin Li       continue;
2509*67e74705SXin Li     A->claim();
2510*67e74705SXin Li   }
2511*67e74705SXin Li 
2512*67e74705SXin Li   Features.push_back(HasHVX  ? "+hvx" : "-hvx");
2513*67e74705SXin Li   Features.push_back(HasHVXD ? "+hvx-double" : "-hvx-double");
2514*67e74705SXin Li }
2515*67e74705SXin Li 
getWebAssemblyTargetFeatures(const ArgList & Args,std::vector<const char * > & Features)2516*67e74705SXin Li static void getWebAssemblyTargetFeatures(const ArgList &Args,
2517*67e74705SXin Li                                          std::vector<const char *> &Features) {
2518*67e74705SXin Li   handleTargetFeaturesGroup(Args, Features, options::OPT_m_wasm_Features_Group);
2519*67e74705SXin Li }
2520*67e74705SXin Li 
getAMDGPUTargetFeatures(const Driver & D,const ArgList & Args,std::vector<const char * > & Features)2521*67e74705SXin Li static void getAMDGPUTargetFeatures(const Driver &D, const ArgList &Args,
2522*67e74705SXin Li                                     std::vector<const char *> &Features) {
2523*67e74705SXin Li   if (const Arg *dAbi = Args.getLastArg(options::OPT_mamdgpu_debugger_abi)) {
2524*67e74705SXin Li     StringRef value = dAbi->getValue();
2525*67e74705SXin Li     if (value == "1.0") {
2526*67e74705SXin Li       Features.push_back("+amdgpu-debugger-insert-nops");
2527*67e74705SXin Li       Features.push_back("+amdgpu-debugger-reserve-regs");
2528*67e74705SXin Li       Features.push_back("+amdgpu-debugger-emit-prologue");
2529*67e74705SXin Li     } else {
2530*67e74705SXin Li       D.Diag(diag::err_drv_clang_unsupported) << dAbi->getAsString(Args);
2531*67e74705SXin Li     }
2532*67e74705SXin Li   }
2533*67e74705SXin Li 
2534*67e74705SXin Li   handleTargetFeaturesGroup(
2535*67e74705SXin Li     Args, Features, options::OPT_m_amdgpu_Features_Group);
2536*67e74705SXin Li }
2537*67e74705SXin Li 
getTargetFeatures(const ToolChain & TC,const llvm::Triple & Triple,const ArgList & Args,ArgStringList & CmdArgs,bool ForAS)2538*67e74705SXin Li static void getTargetFeatures(const ToolChain &TC, const llvm::Triple &Triple,
2539*67e74705SXin Li                               const ArgList &Args, ArgStringList &CmdArgs,
2540*67e74705SXin Li                               bool ForAS) {
2541*67e74705SXin Li   const Driver &D = TC.getDriver();
2542*67e74705SXin Li   std::vector<const char *> Features;
2543*67e74705SXin Li   switch (Triple.getArch()) {
2544*67e74705SXin Li   default:
2545*67e74705SXin Li     break;
2546*67e74705SXin Li   case llvm::Triple::mips:
2547*67e74705SXin Li   case llvm::Triple::mipsel:
2548*67e74705SXin Li   case llvm::Triple::mips64:
2549*67e74705SXin Li   case llvm::Triple::mips64el:
2550*67e74705SXin Li     getMIPSTargetFeatures(D, Triple, Args, Features);
2551*67e74705SXin Li     break;
2552*67e74705SXin Li 
2553*67e74705SXin Li   case llvm::Triple::arm:
2554*67e74705SXin Li   case llvm::Triple::armeb:
2555*67e74705SXin Li   case llvm::Triple::thumb:
2556*67e74705SXin Li   case llvm::Triple::thumbeb:
2557*67e74705SXin Li     getARMTargetFeatures(TC, Triple, Args, Features, ForAS);
2558*67e74705SXin Li     break;
2559*67e74705SXin Li 
2560*67e74705SXin Li   case llvm::Triple::ppc:
2561*67e74705SXin Li   case llvm::Triple::ppc64:
2562*67e74705SXin Li   case llvm::Triple::ppc64le:
2563*67e74705SXin Li     getPPCTargetFeatures(D, Triple, Args, Features);
2564*67e74705SXin Li     break;
2565*67e74705SXin Li   case llvm::Triple::systemz:
2566*67e74705SXin Li     getSystemZTargetFeatures(Args, Features);
2567*67e74705SXin Li     break;
2568*67e74705SXin Li   case llvm::Triple::aarch64:
2569*67e74705SXin Li   case llvm::Triple::aarch64_be:
2570*67e74705SXin Li     getAArch64TargetFeatures(D, Args, Features);
2571*67e74705SXin Li     break;
2572*67e74705SXin Li   case llvm::Triple::x86:
2573*67e74705SXin Li   case llvm::Triple::x86_64:
2574*67e74705SXin Li     getX86TargetFeatures(D, Triple, Args, Features);
2575*67e74705SXin Li     break;
2576*67e74705SXin Li   case llvm::Triple::hexagon:
2577*67e74705SXin Li     getHexagonTargetFeatures(Args, Features);
2578*67e74705SXin Li     break;
2579*67e74705SXin Li   case llvm::Triple::wasm32:
2580*67e74705SXin Li   case llvm::Triple::wasm64:
2581*67e74705SXin Li     getWebAssemblyTargetFeatures(Args, Features);
2582*67e74705SXin Li     break;
2583*67e74705SXin Li   case llvm::Triple::sparc:
2584*67e74705SXin Li   case llvm::Triple::sparcel:
2585*67e74705SXin Li   case llvm::Triple::sparcv9:
2586*67e74705SXin Li     getSparcTargetFeatures(D, Args, Features);
2587*67e74705SXin Li     break;
2588*67e74705SXin Li   case llvm::Triple::r600:
2589*67e74705SXin Li   case llvm::Triple::amdgcn:
2590*67e74705SXin Li     getAMDGPUTargetFeatures(D, Args, Features);
2591*67e74705SXin Li     break;
2592*67e74705SXin Li   }
2593*67e74705SXin Li 
2594*67e74705SXin Li   // Find the last of each feature.
2595*67e74705SXin Li   llvm::StringMap<unsigned> LastOpt;
2596*67e74705SXin Li   for (unsigned I = 0, N = Features.size(); I < N; ++I) {
2597*67e74705SXin Li     const char *Name = Features[I];
2598*67e74705SXin Li     assert(Name[0] == '-' || Name[0] == '+');
2599*67e74705SXin Li     LastOpt[Name + 1] = I;
2600*67e74705SXin Li   }
2601*67e74705SXin Li 
2602*67e74705SXin Li   for (unsigned I = 0, N = Features.size(); I < N; ++I) {
2603*67e74705SXin Li     // If this feature was overridden, ignore it.
2604*67e74705SXin Li     const char *Name = Features[I];
2605*67e74705SXin Li     llvm::StringMap<unsigned>::iterator LastI = LastOpt.find(Name + 1);
2606*67e74705SXin Li     assert(LastI != LastOpt.end());
2607*67e74705SXin Li     unsigned Last = LastI->second;
2608*67e74705SXin Li     if (Last != I)
2609*67e74705SXin Li       continue;
2610*67e74705SXin Li 
2611*67e74705SXin Li     CmdArgs.push_back("-target-feature");
2612*67e74705SXin Li     CmdArgs.push_back(Name);
2613*67e74705SXin Li   }
2614*67e74705SXin Li }
2615*67e74705SXin Li 
2616*67e74705SXin Li static bool
shouldUseExceptionTablesForObjCExceptions(const ObjCRuntime & runtime,const llvm::Triple & Triple)2617*67e74705SXin Li shouldUseExceptionTablesForObjCExceptions(const ObjCRuntime &runtime,
2618*67e74705SXin Li                                           const llvm::Triple &Triple) {
2619*67e74705SXin Li   // We use the zero-cost exception tables for Objective-C if the non-fragile
2620*67e74705SXin Li   // ABI is enabled or when compiling for x86_64 and ARM on Snow Leopard and
2621*67e74705SXin Li   // later.
2622*67e74705SXin Li   if (runtime.isNonFragile())
2623*67e74705SXin Li     return true;
2624*67e74705SXin Li 
2625*67e74705SXin Li   if (!Triple.isMacOSX())
2626*67e74705SXin Li     return false;
2627*67e74705SXin Li 
2628*67e74705SXin Li   return (!Triple.isMacOSXVersionLT(10, 5) &&
2629*67e74705SXin Li           (Triple.getArch() == llvm::Triple::x86_64 ||
2630*67e74705SXin Li            Triple.getArch() == llvm::Triple::arm));
2631*67e74705SXin Li }
2632*67e74705SXin Li 
2633*67e74705SXin Li /// Adds exception related arguments to the driver command arguments. There's a
2634*67e74705SXin Li /// master flag, -fexceptions and also language specific flags to enable/disable
2635*67e74705SXin Li /// C++ and Objective-C exceptions. This makes it possible to for example
2636*67e74705SXin Li /// disable C++ exceptions but enable Objective-C exceptions.
addExceptionArgs(const ArgList & Args,types::ID InputType,const ToolChain & TC,bool KernelOrKext,const ObjCRuntime & objcRuntime,ArgStringList & CmdArgs)2637*67e74705SXin Li static void addExceptionArgs(const ArgList &Args, types::ID InputType,
2638*67e74705SXin Li                              const ToolChain &TC, bool KernelOrKext,
2639*67e74705SXin Li                              const ObjCRuntime &objcRuntime,
2640*67e74705SXin Li                              ArgStringList &CmdArgs) {
2641*67e74705SXin Li   const Driver &D = TC.getDriver();
2642*67e74705SXin Li   const llvm::Triple &Triple = TC.getTriple();
2643*67e74705SXin Li 
2644*67e74705SXin Li   if (KernelOrKext) {
2645*67e74705SXin Li     // -mkernel and -fapple-kext imply no exceptions, so claim exception related
2646*67e74705SXin Li     // arguments now to avoid warnings about unused arguments.
2647*67e74705SXin Li     Args.ClaimAllArgs(options::OPT_fexceptions);
2648*67e74705SXin Li     Args.ClaimAllArgs(options::OPT_fno_exceptions);
2649*67e74705SXin Li     Args.ClaimAllArgs(options::OPT_fobjc_exceptions);
2650*67e74705SXin Li     Args.ClaimAllArgs(options::OPT_fno_objc_exceptions);
2651*67e74705SXin Li     Args.ClaimAllArgs(options::OPT_fcxx_exceptions);
2652*67e74705SXin Li     Args.ClaimAllArgs(options::OPT_fno_cxx_exceptions);
2653*67e74705SXin Li     return;
2654*67e74705SXin Li   }
2655*67e74705SXin Li 
2656*67e74705SXin Li   // See if the user explicitly enabled exceptions.
2657*67e74705SXin Li   bool EH = Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions,
2658*67e74705SXin Li                          false);
2659*67e74705SXin Li 
2660*67e74705SXin Li   // Obj-C exceptions are enabled by default, regardless of -fexceptions. This
2661*67e74705SXin Li   // is not necessarily sensible, but follows GCC.
2662*67e74705SXin Li   if (types::isObjC(InputType) &&
2663*67e74705SXin Li       Args.hasFlag(options::OPT_fobjc_exceptions,
2664*67e74705SXin Li                    options::OPT_fno_objc_exceptions, true)) {
2665*67e74705SXin Li     CmdArgs.push_back("-fobjc-exceptions");
2666*67e74705SXin Li 
2667*67e74705SXin Li     EH |= shouldUseExceptionTablesForObjCExceptions(objcRuntime, Triple);
2668*67e74705SXin Li   }
2669*67e74705SXin Li 
2670*67e74705SXin Li   if (types::isCXX(InputType)) {
2671*67e74705SXin Li     // Disable C++ EH by default on XCore and PS4.
2672*67e74705SXin Li     bool CXXExceptionsEnabled =
2673*67e74705SXin Li         Triple.getArch() != llvm::Triple::xcore && !Triple.isPS4CPU();
2674*67e74705SXin Li     Arg *ExceptionArg = Args.getLastArg(
2675*67e74705SXin Li         options::OPT_fcxx_exceptions, options::OPT_fno_cxx_exceptions,
2676*67e74705SXin Li         options::OPT_fexceptions, options::OPT_fno_exceptions);
2677*67e74705SXin Li     if (ExceptionArg)
2678*67e74705SXin Li       CXXExceptionsEnabled =
2679*67e74705SXin Li           ExceptionArg->getOption().matches(options::OPT_fcxx_exceptions) ||
2680*67e74705SXin Li           ExceptionArg->getOption().matches(options::OPT_fexceptions);
2681*67e74705SXin Li 
2682*67e74705SXin Li     if (CXXExceptionsEnabled) {
2683*67e74705SXin Li       if (Triple.isPS4CPU()) {
2684*67e74705SXin Li         ToolChain::RTTIMode RTTIMode = TC.getRTTIMode();
2685*67e74705SXin Li         assert(ExceptionArg &&
2686*67e74705SXin Li                "On the PS4 exceptions should only be enabled if passing "
2687*67e74705SXin Li                "an argument");
2688*67e74705SXin Li         if (RTTIMode == ToolChain::RM_DisabledExplicitly) {
2689*67e74705SXin Li           const Arg *RTTIArg = TC.getRTTIArg();
2690*67e74705SXin Li           assert(RTTIArg && "RTTI disabled explicitly but no RTTIArg!");
2691*67e74705SXin Li           D.Diag(diag::err_drv_argument_not_allowed_with)
2692*67e74705SXin Li               << RTTIArg->getAsString(Args) << ExceptionArg->getAsString(Args);
2693*67e74705SXin Li         } else if (RTTIMode == ToolChain::RM_EnabledImplicitly)
2694*67e74705SXin Li           D.Diag(diag::warn_drv_enabling_rtti_with_exceptions);
2695*67e74705SXin Li       } else
2696*67e74705SXin Li         assert(TC.getRTTIMode() != ToolChain::RM_DisabledImplicitly);
2697*67e74705SXin Li 
2698*67e74705SXin Li       CmdArgs.push_back("-fcxx-exceptions");
2699*67e74705SXin Li 
2700*67e74705SXin Li       EH = true;
2701*67e74705SXin Li     }
2702*67e74705SXin Li   }
2703*67e74705SXin Li 
2704*67e74705SXin Li   if (EH)
2705*67e74705SXin Li     CmdArgs.push_back("-fexceptions");
2706*67e74705SXin Li }
2707*67e74705SXin Li 
ShouldDisableAutolink(const ArgList & Args,const ToolChain & TC)2708*67e74705SXin Li static bool ShouldDisableAutolink(const ArgList &Args, const ToolChain &TC) {
2709*67e74705SXin Li   bool Default = true;
2710*67e74705SXin Li   if (TC.getTriple().isOSDarwin()) {
2711*67e74705SXin Li     // The native darwin assembler doesn't support the linker_option directives,
2712*67e74705SXin Li     // so we disable them if we think the .s file will be passed to it.
2713*67e74705SXin Li     Default = TC.useIntegratedAs();
2714*67e74705SXin Li   }
2715*67e74705SXin Li   return !Args.hasFlag(options::OPT_fautolink, options::OPT_fno_autolink,
2716*67e74705SXin Li                        Default);
2717*67e74705SXin Li }
2718*67e74705SXin Li 
ShouldDisableDwarfDirectory(const ArgList & Args,const ToolChain & TC)2719*67e74705SXin Li static bool ShouldDisableDwarfDirectory(const ArgList &Args,
2720*67e74705SXin Li                                         const ToolChain &TC) {
2721*67e74705SXin Li   bool UseDwarfDirectory =
2722*67e74705SXin Li       Args.hasFlag(options::OPT_fdwarf_directory_asm,
2723*67e74705SXin Li                    options::OPT_fno_dwarf_directory_asm, TC.useIntegratedAs());
2724*67e74705SXin Li   return !UseDwarfDirectory;
2725*67e74705SXin Li }
2726*67e74705SXin Li 
2727*67e74705SXin Li /// \brief Check whether the given input tree contains any compilation actions.
ContainsCompileAction(const Action * A)2728*67e74705SXin Li static bool ContainsCompileAction(const Action *A) {
2729*67e74705SXin Li   if (isa<CompileJobAction>(A) || isa<BackendJobAction>(A))
2730*67e74705SXin Li     return true;
2731*67e74705SXin Li 
2732*67e74705SXin Li   for (const auto &AI : A->inputs())
2733*67e74705SXin Li     if (ContainsCompileAction(AI))
2734*67e74705SXin Li       return true;
2735*67e74705SXin Li 
2736*67e74705SXin Li   return false;
2737*67e74705SXin Li }
2738*67e74705SXin Li 
2739*67e74705SXin Li /// \brief Check if -relax-all should be passed to the internal assembler.
2740*67e74705SXin Li /// This is done by default when compiling non-assembler source with -O0.
UseRelaxAll(Compilation & C,const ArgList & Args)2741*67e74705SXin Li static bool UseRelaxAll(Compilation &C, const ArgList &Args) {
2742*67e74705SXin Li   bool RelaxDefault = true;
2743*67e74705SXin Li 
2744*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_O_Group))
2745*67e74705SXin Li     RelaxDefault = A->getOption().matches(options::OPT_O0);
2746*67e74705SXin Li 
2747*67e74705SXin Li   if (RelaxDefault) {
2748*67e74705SXin Li     RelaxDefault = false;
2749*67e74705SXin Li     for (const auto &Act : C.getActions()) {
2750*67e74705SXin Li       if (ContainsCompileAction(Act)) {
2751*67e74705SXin Li         RelaxDefault = true;
2752*67e74705SXin Li         break;
2753*67e74705SXin Li       }
2754*67e74705SXin Li     }
2755*67e74705SXin Li   }
2756*67e74705SXin Li 
2757*67e74705SXin Li   return Args.hasFlag(options::OPT_mrelax_all, options::OPT_mno_relax_all,
2758*67e74705SXin Li                       RelaxDefault);
2759*67e74705SXin Li }
2760*67e74705SXin Li 
2761*67e74705SXin Li // Convert an arg of the form "-gN" or "-ggdbN" or one of their aliases
2762*67e74705SXin Li // to the corresponding DebugInfoKind.
DebugLevelToInfoKind(const Arg & A)2763*67e74705SXin Li static codegenoptions::DebugInfoKind DebugLevelToInfoKind(const Arg &A) {
2764*67e74705SXin Li   assert(A.getOption().matches(options::OPT_gN_Group) &&
2765*67e74705SXin Li          "Not a -g option that specifies a debug-info level");
2766*67e74705SXin Li   if (A.getOption().matches(options::OPT_g0) ||
2767*67e74705SXin Li       A.getOption().matches(options::OPT_ggdb0))
2768*67e74705SXin Li     return codegenoptions::NoDebugInfo;
2769*67e74705SXin Li   if (A.getOption().matches(options::OPT_gline_tables_only) ||
2770*67e74705SXin Li       A.getOption().matches(options::OPT_ggdb1))
2771*67e74705SXin Li     return codegenoptions::DebugLineTablesOnly;
2772*67e74705SXin Li   return codegenoptions::LimitedDebugInfo;
2773*67e74705SXin Li }
2774*67e74705SXin Li 
2775*67e74705SXin Li // Extract the integer N from a string spelled "-dwarf-N", returning 0
2776*67e74705SXin Li // on mismatch. The StringRef input (rather than an Arg) allows
2777*67e74705SXin Li // for use by the "-Xassembler" option parser.
DwarfVersionNum(StringRef ArgValue)2778*67e74705SXin Li static unsigned DwarfVersionNum(StringRef ArgValue) {
2779*67e74705SXin Li   return llvm::StringSwitch<unsigned>(ArgValue)
2780*67e74705SXin Li       .Case("-gdwarf-2", 2)
2781*67e74705SXin Li       .Case("-gdwarf-3", 3)
2782*67e74705SXin Li       .Case("-gdwarf-4", 4)
2783*67e74705SXin Li       .Case("-gdwarf-5", 5)
2784*67e74705SXin Li       .Default(0);
2785*67e74705SXin Li }
2786*67e74705SXin Li 
RenderDebugEnablingArgs(const ArgList & Args,ArgStringList & CmdArgs,codegenoptions::DebugInfoKind DebugInfoKind,unsigned DwarfVersion,llvm::DebuggerKind DebuggerTuning)2787*67e74705SXin Li static void RenderDebugEnablingArgs(const ArgList &Args, ArgStringList &CmdArgs,
2788*67e74705SXin Li                                     codegenoptions::DebugInfoKind DebugInfoKind,
2789*67e74705SXin Li                                     unsigned DwarfVersion,
2790*67e74705SXin Li                                     llvm::DebuggerKind DebuggerTuning) {
2791*67e74705SXin Li   switch (DebugInfoKind) {
2792*67e74705SXin Li   case codegenoptions::DebugLineTablesOnly:
2793*67e74705SXin Li     CmdArgs.push_back("-debug-info-kind=line-tables-only");
2794*67e74705SXin Li     break;
2795*67e74705SXin Li   case codegenoptions::LimitedDebugInfo:
2796*67e74705SXin Li     CmdArgs.push_back("-debug-info-kind=limited");
2797*67e74705SXin Li     break;
2798*67e74705SXin Li   case codegenoptions::FullDebugInfo:
2799*67e74705SXin Li     CmdArgs.push_back("-debug-info-kind=standalone");
2800*67e74705SXin Li     break;
2801*67e74705SXin Li   default:
2802*67e74705SXin Li     break;
2803*67e74705SXin Li   }
2804*67e74705SXin Li   if (DwarfVersion > 0)
2805*67e74705SXin Li     CmdArgs.push_back(
2806*67e74705SXin Li         Args.MakeArgString("-dwarf-version=" + Twine(DwarfVersion)));
2807*67e74705SXin Li   switch (DebuggerTuning) {
2808*67e74705SXin Li   case llvm::DebuggerKind::GDB:
2809*67e74705SXin Li     CmdArgs.push_back("-debugger-tuning=gdb");
2810*67e74705SXin Li     break;
2811*67e74705SXin Li   case llvm::DebuggerKind::LLDB:
2812*67e74705SXin Li     CmdArgs.push_back("-debugger-tuning=lldb");
2813*67e74705SXin Li     break;
2814*67e74705SXin Li   case llvm::DebuggerKind::SCE:
2815*67e74705SXin Li     CmdArgs.push_back("-debugger-tuning=sce");
2816*67e74705SXin Li     break;
2817*67e74705SXin Li   default:
2818*67e74705SXin Li     break;
2819*67e74705SXin Li   }
2820*67e74705SXin Li }
2821*67e74705SXin Li 
CollectArgsForIntegratedAssembler(Compilation & C,const ArgList & Args,ArgStringList & CmdArgs,const Driver & D)2822*67e74705SXin Li static void CollectArgsForIntegratedAssembler(Compilation &C,
2823*67e74705SXin Li                                               const ArgList &Args,
2824*67e74705SXin Li                                               ArgStringList &CmdArgs,
2825*67e74705SXin Li                                               const Driver &D) {
2826*67e74705SXin Li   if (UseRelaxAll(C, Args))
2827*67e74705SXin Li     CmdArgs.push_back("-mrelax-all");
2828*67e74705SXin Li 
2829*67e74705SXin Li   // Only default to -mincremental-linker-compatible if we think we are
2830*67e74705SXin Li   // targeting the MSVC linker.
2831*67e74705SXin Li   bool DefaultIncrementalLinkerCompatible =
2832*67e74705SXin Li       C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment();
2833*67e74705SXin Li   if (Args.hasFlag(options::OPT_mincremental_linker_compatible,
2834*67e74705SXin Li                    options::OPT_mno_incremental_linker_compatible,
2835*67e74705SXin Li                    DefaultIncrementalLinkerCompatible))
2836*67e74705SXin Li     CmdArgs.push_back("-mincremental-linker-compatible");
2837*67e74705SXin Li 
2838*67e74705SXin Li   // When passing -I arguments to the assembler we sometimes need to
2839*67e74705SXin Li   // unconditionally take the next argument.  For example, when parsing
2840*67e74705SXin Li   // '-Wa,-I -Wa,foo' we need to accept the -Wa,foo arg after seeing the
2841*67e74705SXin Li   // -Wa,-I arg and when parsing '-Wa,-I,foo' we need to accept the 'foo'
2842*67e74705SXin Li   // arg after parsing the '-I' arg.
2843*67e74705SXin Li   bool TakeNextArg = false;
2844*67e74705SXin Li 
2845*67e74705SXin Li   // When using an integrated assembler, translate -Wa, and -Xassembler
2846*67e74705SXin Li   // options.
2847*67e74705SXin Li   bool CompressDebugSections = false;
2848*67e74705SXin Li 
2849*67e74705SXin Li   bool UseRelaxRelocations = ENABLE_X86_RELAX_RELOCATIONS;
2850*67e74705SXin Li   const char *MipsTargetFeature = nullptr;
2851*67e74705SXin Li   for (const Arg *A :
2852*67e74705SXin Li        Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) {
2853*67e74705SXin Li     A->claim();
2854*67e74705SXin Li 
2855*67e74705SXin Li     for (StringRef Value : A->getValues()) {
2856*67e74705SXin Li       if (TakeNextArg) {
2857*67e74705SXin Li         CmdArgs.push_back(Value.data());
2858*67e74705SXin Li         TakeNextArg = false;
2859*67e74705SXin Li         continue;
2860*67e74705SXin Li       }
2861*67e74705SXin Li 
2862*67e74705SXin Li       switch (C.getDefaultToolChain().getArch()) {
2863*67e74705SXin Li       default:
2864*67e74705SXin Li         break;
2865*67e74705SXin Li       case llvm::Triple::mips:
2866*67e74705SXin Li       case llvm::Triple::mipsel:
2867*67e74705SXin Li       case llvm::Triple::mips64:
2868*67e74705SXin Li       case llvm::Triple::mips64el:
2869*67e74705SXin Li         if (Value == "--trap") {
2870*67e74705SXin Li           CmdArgs.push_back("-target-feature");
2871*67e74705SXin Li           CmdArgs.push_back("+use-tcc-in-div");
2872*67e74705SXin Li           continue;
2873*67e74705SXin Li         }
2874*67e74705SXin Li         if (Value == "--break") {
2875*67e74705SXin Li           CmdArgs.push_back("-target-feature");
2876*67e74705SXin Li           CmdArgs.push_back("-use-tcc-in-div");
2877*67e74705SXin Li           continue;
2878*67e74705SXin Li         }
2879*67e74705SXin Li         if (Value.startswith("-msoft-float")) {
2880*67e74705SXin Li           CmdArgs.push_back("-target-feature");
2881*67e74705SXin Li           CmdArgs.push_back("+soft-float");
2882*67e74705SXin Li           continue;
2883*67e74705SXin Li         }
2884*67e74705SXin Li         if (Value.startswith("-mhard-float")) {
2885*67e74705SXin Li           CmdArgs.push_back("-target-feature");
2886*67e74705SXin Li           CmdArgs.push_back("-soft-float");
2887*67e74705SXin Li           continue;
2888*67e74705SXin Li         }
2889*67e74705SXin Li 
2890*67e74705SXin Li         MipsTargetFeature = llvm::StringSwitch<const char *>(Value)
2891*67e74705SXin Li                                 .Case("-mips1", "+mips1")
2892*67e74705SXin Li                                 .Case("-mips2", "+mips2")
2893*67e74705SXin Li                                 .Case("-mips3", "+mips3")
2894*67e74705SXin Li                                 .Case("-mips4", "+mips4")
2895*67e74705SXin Li                                 .Case("-mips5", "+mips5")
2896*67e74705SXin Li                                 .Case("-mips32", "+mips32")
2897*67e74705SXin Li                                 .Case("-mips32r2", "+mips32r2")
2898*67e74705SXin Li                                 .Case("-mips32r3", "+mips32r3")
2899*67e74705SXin Li                                 .Case("-mips32r5", "+mips32r5")
2900*67e74705SXin Li                                 .Case("-mips32r6", "+mips32r6")
2901*67e74705SXin Li                                 .Case("-mips64", "+mips64")
2902*67e74705SXin Li                                 .Case("-mips64r2", "+mips64r2")
2903*67e74705SXin Li                                 .Case("-mips64r3", "+mips64r3")
2904*67e74705SXin Li                                 .Case("-mips64r5", "+mips64r5")
2905*67e74705SXin Li                                 .Case("-mips64r6", "+mips64r6")
2906*67e74705SXin Li                                 .Default(nullptr);
2907*67e74705SXin Li         if (MipsTargetFeature)
2908*67e74705SXin Li           continue;
2909*67e74705SXin Li       }
2910*67e74705SXin Li 
2911*67e74705SXin Li       if (Value == "-force_cpusubtype_ALL") {
2912*67e74705SXin Li         // Do nothing, this is the default and we don't support anything else.
2913*67e74705SXin Li       } else if (Value == "-L") {
2914*67e74705SXin Li         CmdArgs.push_back("-msave-temp-labels");
2915*67e74705SXin Li       } else if (Value == "--fatal-warnings") {
2916*67e74705SXin Li         CmdArgs.push_back("-massembler-fatal-warnings");
2917*67e74705SXin Li       } else if (Value == "--noexecstack") {
2918*67e74705SXin Li         CmdArgs.push_back("-mnoexecstack");
2919*67e74705SXin Li       } else if (Value == "-compress-debug-sections" ||
2920*67e74705SXin Li                  Value == "--compress-debug-sections") {
2921*67e74705SXin Li         CompressDebugSections = true;
2922*67e74705SXin Li       } else if (Value == "-nocompress-debug-sections" ||
2923*67e74705SXin Li                  Value == "--nocompress-debug-sections") {
2924*67e74705SXin Li         CompressDebugSections = false;
2925*67e74705SXin Li       } else if (Value == "-mrelax-relocations=yes" ||
2926*67e74705SXin Li                  Value == "--mrelax-relocations=yes") {
2927*67e74705SXin Li         UseRelaxRelocations = true;
2928*67e74705SXin Li       } else if (Value == "-mrelax-relocations=no" ||
2929*67e74705SXin Li                  Value == "--mrelax-relocations=no") {
2930*67e74705SXin Li         UseRelaxRelocations = false;
2931*67e74705SXin Li       } else if (Value.startswith("-I")) {
2932*67e74705SXin Li         CmdArgs.push_back(Value.data());
2933*67e74705SXin Li         // We need to consume the next argument if the current arg is a plain
2934*67e74705SXin Li         // -I. The next arg will be the include directory.
2935*67e74705SXin Li         if (Value == "-I")
2936*67e74705SXin Li           TakeNextArg = true;
2937*67e74705SXin Li       } else if (Value.startswith("-gdwarf-")) {
2938*67e74705SXin Li         // "-gdwarf-N" options are not cc1as options.
2939*67e74705SXin Li         unsigned DwarfVersion = DwarfVersionNum(Value);
2940*67e74705SXin Li         if (DwarfVersion == 0) { // Send it onward, and let cc1as complain.
2941*67e74705SXin Li           CmdArgs.push_back(Value.data());
2942*67e74705SXin Li         } else {
2943*67e74705SXin Li           RenderDebugEnablingArgs(Args, CmdArgs,
2944*67e74705SXin Li                                   codegenoptions::LimitedDebugInfo,
2945*67e74705SXin Li                                   DwarfVersion, llvm::DebuggerKind::Default);
2946*67e74705SXin Li         }
2947*67e74705SXin Li       } else if (Value.startswith("-mcpu") || Value.startswith("-mfpu") ||
2948*67e74705SXin Li                  Value.startswith("-mhwdiv") || Value.startswith("-march")) {
2949*67e74705SXin Li         // Do nothing, we'll validate it later.
2950*67e74705SXin Li       } else {
2951*67e74705SXin Li         D.Diag(diag::err_drv_unsupported_option_argument)
2952*67e74705SXin Li             << A->getOption().getName() << Value;
2953*67e74705SXin Li       }
2954*67e74705SXin Li     }
2955*67e74705SXin Li   }
2956*67e74705SXin Li   if (CompressDebugSections) {
2957*67e74705SXin Li     if (llvm::zlib::isAvailable())
2958*67e74705SXin Li       CmdArgs.push_back("-compress-debug-sections");
2959*67e74705SXin Li     else
2960*67e74705SXin Li       D.Diag(diag::warn_debug_compression_unavailable);
2961*67e74705SXin Li   }
2962*67e74705SXin Li   if (UseRelaxRelocations)
2963*67e74705SXin Li     CmdArgs.push_back("--mrelax-relocations");
2964*67e74705SXin Li   if (MipsTargetFeature != nullptr) {
2965*67e74705SXin Li     CmdArgs.push_back("-target-feature");
2966*67e74705SXin Li     CmdArgs.push_back(MipsTargetFeature);
2967*67e74705SXin Li   }
2968*67e74705SXin Li }
2969*67e74705SXin Li 
2970*67e74705SXin Li // This adds the static libclang_rt.builtins-arch.a directly to the command line
2971*67e74705SXin Li // FIXME: Make sure we can also emit shared objects if they're requested
2972*67e74705SXin Li // and available, check for possible errors, etc.
addClangRT(const ToolChain & TC,const ArgList & Args,ArgStringList & CmdArgs)2973*67e74705SXin Li static void addClangRT(const ToolChain &TC, const ArgList &Args,
2974*67e74705SXin Li                        ArgStringList &CmdArgs) {
2975*67e74705SXin Li   CmdArgs.push_back(TC.getCompilerRTArgString(Args, "builtins"));
2976*67e74705SXin Li }
2977*67e74705SXin Li 
2978*67e74705SXin Li namespace {
2979*67e74705SXin Li enum OpenMPRuntimeKind {
2980*67e74705SXin Li   /// An unknown OpenMP runtime. We can't generate effective OpenMP code
2981*67e74705SXin Li   /// without knowing what runtime to target.
2982*67e74705SXin Li   OMPRT_Unknown,
2983*67e74705SXin Li 
2984*67e74705SXin Li   /// The LLVM OpenMP runtime. When completed and integrated, this will become
2985*67e74705SXin Li   /// the default for Clang.
2986*67e74705SXin Li   OMPRT_OMP,
2987*67e74705SXin Li 
2988*67e74705SXin Li   /// The GNU OpenMP runtime. Clang doesn't support generating OpenMP code for
2989*67e74705SXin Li   /// this runtime but can swallow the pragmas, and find and link against the
2990*67e74705SXin Li   /// runtime library itself.
2991*67e74705SXin Li   OMPRT_GOMP,
2992*67e74705SXin Li 
2993*67e74705SXin Li   /// The legacy name for the LLVM OpenMP runtime from when it was the Intel
2994*67e74705SXin Li   /// OpenMP runtime. We support this mode for users with existing dependencies
2995*67e74705SXin Li   /// on this runtime library name.
2996*67e74705SXin Li   OMPRT_IOMP5
2997*67e74705SXin Li };
2998*67e74705SXin Li }
2999*67e74705SXin Li 
3000*67e74705SXin Li /// Compute the desired OpenMP runtime from the flag provided.
getOpenMPRuntime(const ToolChain & TC,const ArgList & Args)3001*67e74705SXin Li static OpenMPRuntimeKind getOpenMPRuntime(const ToolChain &TC,
3002*67e74705SXin Li                                           const ArgList &Args) {
3003*67e74705SXin Li   StringRef RuntimeName(CLANG_DEFAULT_OPENMP_RUNTIME);
3004*67e74705SXin Li 
3005*67e74705SXin Li   const Arg *A = Args.getLastArg(options::OPT_fopenmp_EQ);
3006*67e74705SXin Li   if (A)
3007*67e74705SXin Li     RuntimeName = A->getValue();
3008*67e74705SXin Li 
3009*67e74705SXin Li   auto RT = llvm::StringSwitch<OpenMPRuntimeKind>(RuntimeName)
3010*67e74705SXin Li                 .Case("libomp", OMPRT_OMP)
3011*67e74705SXin Li                 .Case("libgomp", OMPRT_GOMP)
3012*67e74705SXin Li                 .Case("libiomp5", OMPRT_IOMP5)
3013*67e74705SXin Li                 .Default(OMPRT_Unknown);
3014*67e74705SXin Li 
3015*67e74705SXin Li   if (RT == OMPRT_Unknown) {
3016*67e74705SXin Li     if (A)
3017*67e74705SXin Li       TC.getDriver().Diag(diag::err_drv_unsupported_option_argument)
3018*67e74705SXin Li           << A->getOption().getName() << A->getValue();
3019*67e74705SXin Li     else
3020*67e74705SXin Li       // FIXME: We could use a nicer diagnostic here.
3021*67e74705SXin Li       TC.getDriver().Diag(diag::err_drv_unsupported_opt) << "-fopenmp";
3022*67e74705SXin Li   }
3023*67e74705SXin Li 
3024*67e74705SXin Li   return RT;
3025*67e74705SXin Li }
3026*67e74705SXin Li 
addOpenMPRuntime(ArgStringList & CmdArgs,const ToolChain & TC,const ArgList & Args)3027*67e74705SXin Li static void addOpenMPRuntime(ArgStringList &CmdArgs, const ToolChain &TC,
3028*67e74705SXin Li                               const ArgList &Args) {
3029*67e74705SXin Li   if (!Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
3030*67e74705SXin Li                     options::OPT_fno_openmp, false))
3031*67e74705SXin Li     return;
3032*67e74705SXin Li 
3033*67e74705SXin Li   switch (getOpenMPRuntime(TC, Args)) {
3034*67e74705SXin Li   case OMPRT_OMP:
3035*67e74705SXin Li     CmdArgs.push_back("-lomp");
3036*67e74705SXin Li     break;
3037*67e74705SXin Li   case OMPRT_GOMP:
3038*67e74705SXin Li     CmdArgs.push_back("-lgomp");
3039*67e74705SXin Li     break;
3040*67e74705SXin Li   case OMPRT_IOMP5:
3041*67e74705SXin Li     CmdArgs.push_back("-liomp5");
3042*67e74705SXin Li     break;
3043*67e74705SXin Li   case OMPRT_Unknown:
3044*67e74705SXin Li     // Already diagnosed.
3045*67e74705SXin Li     break;
3046*67e74705SXin Li   }
3047*67e74705SXin Li }
3048*67e74705SXin Li 
addSanitizerRuntime(const ToolChain & TC,const ArgList & Args,ArgStringList & CmdArgs,StringRef Sanitizer,bool IsShared,bool IsWhole)3049*67e74705SXin Li static void addSanitizerRuntime(const ToolChain &TC, const ArgList &Args,
3050*67e74705SXin Li                                 ArgStringList &CmdArgs, StringRef Sanitizer,
3051*67e74705SXin Li                                 bool IsShared, bool IsWhole) {
3052*67e74705SXin Li   // Wrap any static runtimes that must be forced into executable in
3053*67e74705SXin Li   // whole-archive.
3054*67e74705SXin Li   if (IsWhole) CmdArgs.push_back("-whole-archive");
3055*67e74705SXin Li   CmdArgs.push_back(TC.getCompilerRTArgString(Args, Sanitizer, IsShared));
3056*67e74705SXin Li   if (IsWhole) CmdArgs.push_back("-no-whole-archive");
3057*67e74705SXin Li }
3058*67e74705SXin Li 
3059*67e74705SXin Li // Tries to use a file with the list of dynamic symbols that need to be exported
3060*67e74705SXin Li // from the runtime library. Returns true if the file was found.
addSanitizerDynamicList(const ToolChain & TC,const ArgList & Args,ArgStringList & CmdArgs,StringRef Sanitizer)3061*67e74705SXin Li static bool addSanitizerDynamicList(const ToolChain &TC, const ArgList &Args,
3062*67e74705SXin Li                                     ArgStringList &CmdArgs,
3063*67e74705SXin Li                                     StringRef Sanitizer) {
3064*67e74705SXin Li   SmallString<128> SanRT(TC.getCompilerRT(Args, Sanitizer));
3065*67e74705SXin Li   if (llvm::sys::fs::exists(SanRT + ".syms")) {
3066*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString("--dynamic-list=" + SanRT + ".syms"));
3067*67e74705SXin Li     return true;
3068*67e74705SXin Li   }
3069*67e74705SXin Li   return false;
3070*67e74705SXin Li }
3071*67e74705SXin Li 
linkSanitizerRuntimeDeps(const ToolChain & TC,ArgStringList & CmdArgs)3072*67e74705SXin Li static void linkSanitizerRuntimeDeps(const ToolChain &TC,
3073*67e74705SXin Li                                      ArgStringList &CmdArgs) {
3074*67e74705SXin Li   // Force linking against the system libraries sanitizers depends on
3075*67e74705SXin Li   // (see PR15823 why this is necessary).
3076*67e74705SXin Li   CmdArgs.push_back("--no-as-needed");
3077*67e74705SXin Li   CmdArgs.push_back("-lpthread");
3078*67e74705SXin Li   CmdArgs.push_back("-lrt");
3079*67e74705SXin Li   CmdArgs.push_back("-lm");
3080*67e74705SXin Li   // There's no libdl on FreeBSD.
3081*67e74705SXin Li   if (TC.getTriple().getOS() != llvm::Triple::FreeBSD)
3082*67e74705SXin Li     CmdArgs.push_back("-ldl");
3083*67e74705SXin Li }
3084*67e74705SXin Li 
3085*67e74705SXin Li static void
collectSanitizerRuntimes(const ToolChain & TC,const ArgList & Args,SmallVectorImpl<StringRef> & SharedRuntimes,SmallVectorImpl<StringRef> & StaticRuntimes,SmallVectorImpl<StringRef> & NonWholeStaticRuntimes,SmallVectorImpl<StringRef> & HelperStaticRuntimes,SmallVectorImpl<StringRef> & RequiredSymbols)3086*67e74705SXin Li collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
3087*67e74705SXin Li                          SmallVectorImpl<StringRef> &SharedRuntimes,
3088*67e74705SXin Li                          SmallVectorImpl<StringRef> &StaticRuntimes,
3089*67e74705SXin Li                          SmallVectorImpl<StringRef> &NonWholeStaticRuntimes,
3090*67e74705SXin Li                          SmallVectorImpl<StringRef> &HelperStaticRuntimes,
3091*67e74705SXin Li                          SmallVectorImpl<StringRef> &RequiredSymbols) {
3092*67e74705SXin Li   const SanitizerArgs &SanArgs = TC.getSanitizerArgs();
3093*67e74705SXin Li   // Collect shared runtimes.
3094*67e74705SXin Li   if (SanArgs.needsAsanRt() && SanArgs.needsSharedAsanRt()) {
3095*67e74705SXin Li     SharedRuntimes.push_back("asan");
3096*67e74705SXin Li   }
3097*67e74705SXin Li   // The stats_client library is also statically linked into DSOs.
3098*67e74705SXin Li   if (SanArgs.needsStatsRt())
3099*67e74705SXin Li     StaticRuntimes.push_back("stats_client");
3100*67e74705SXin Li 
3101*67e74705SXin Li   // Collect static runtimes.
3102*67e74705SXin Li   if (Args.hasArg(options::OPT_shared) || TC.getTriple().isAndroid()) {
3103*67e74705SXin Li     // Don't link static runtimes into DSOs or if compiling for Android.
3104*67e74705SXin Li     return;
3105*67e74705SXin Li   }
3106*67e74705SXin Li   if (SanArgs.needsAsanRt()) {
3107*67e74705SXin Li     if (SanArgs.needsSharedAsanRt()) {
3108*67e74705SXin Li       HelperStaticRuntimes.push_back("asan-preinit");
3109*67e74705SXin Li     } else {
3110*67e74705SXin Li       StaticRuntimes.push_back("asan");
3111*67e74705SXin Li       if (SanArgs.linkCXXRuntimes())
3112*67e74705SXin Li         StaticRuntimes.push_back("asan_cxx");
3113*67e74705SXin Li     }
3114*67e74705SXin Li   }
3115*67e74705SXin Li   if (SanArgs.needsDfsanRt())
3116*67e74705SXin Li     StaticRuntimes.push_back("dfsan");
3117*67e74705SXin Li   if (SanArgs.needsLsanRt())
3118*67e74705SXin Li     StaticRuntimes.push_back("lsan");
3119*67e74705SXin Li   if (SanArgs.needsMsanRt()) {
3120*67e74705SXin Li     StaticRuntimes.push_back("msan");
3121*67e74705SXin Li     if (SanArgs.linkCXXRuntimes())
3122*67e74705SXin Li       StaticRuntimes.push_back("msan_cxx");
3123*67e74705SXin Li   }
3124*67e74705SXin Li   if (SanArgs.needsTsanRt()) {
3125*67e74705SXin Li     StaticRuntimes.push_back("tsan");
3126*67e74705SXin Li     if (SanArgs.linkCXXRuntimes())
3127*67e74705SXin Li       StaticRuntimes.push_back("tsan_cxx");
3128*67e74705SXin Li   }
3129*67e74705SXin Li   if (SanArgs.needsUbsanRt()) {
3130*67e74705SXin Li     StaticRuntimes.push_back("ubsan_standalone");
3131*67e74705SXin Li     if (SanArgs.linkCXXRuntimes())
3132*67e74705SXin Li       StaticRuntimes.push_back("ubsan_standalone_cxx");
3133*67e74705SXin Li   }
3134*67e74705SXin Li   if (SanArgs.needsSafeStackRt())
3135*67e74705SXin Li     StaticRuntimes.push_back("safestack");
3136*67e74705SXin Li   if (SanArgs.needsCfiRt())
3137*67e74705SXin Li     StaticRuntimes.push_back("cfi");
3138*67e74705SXin Li   if (SanArgs.needsCfiDiagRt()) {
3139*67e74705SXin Li     StaticRuntimes.push_back("cfi_diag");
3140*67e74705SXin Li     if (SanArgs.linkCXXRuntimes())
3141*67e74705SXin Li       StaticRuntimes.push_back("ubsan_standalone_cxx");
3142*67e74705SXin Li   }
3143*67e74705SXin Li   if (SanArgs.needsStatsRt()) {
3144*67e74705SXin Li     NonWholeStaticRuntimes.push_back("stats");
3145*67e74705SXin Li     RequiredSymbols.push_back("__sanitizer_stats_register");
3146*67e74705SXin Li   }
3147*67e74705SXin Li   if (SanArgs.needsEsanRt())
3148*67e74705SXin Li     StaticRuntimes.push_back("esan");
3149*67e74705SXin Li }
3150*67e74705SXin Li 
3151*67e74705SXin Li // Should be called before we add system libraries (C++ ABI, libstdc++/libc++,
3152*67e74705SXin Li // C runtime, etc). Returns true if sanitizer system deps need to be linked in.
addSanitizerRuntimes(const ToolChain & TC,const ArgList & Args,ArgStringList & CmdArgs)3153*67e74705SXin Li static bool addSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
3154*67e74705SXin Li                                  ArgStringList &CmdArgs) {
3155*67e74705SXin Li   SmallVector<StringRef, 4> SharedRuntimes, StaticRuntimes,
3156*67e74705SXin Li       NonWholeStaticRuntimes, HelperStaticRuntimes, RequiredSymbols;
3157*67e74705SXin Li   collectSanitizerRuntimes(TC, Args, SharedRuntimes, StaticRuntimes,
3158*67e74705SXin Li                            NonWholeStaticRuntimes, HelperStaticRuntimes,
3159*67e74705SXin Li                            RequiredSymbols);
3160*67e74705SXin Li   for (auto RT : SharedRuntimes)
3161*67e74705SXin Li     addSanitizerRuntime(TC, Args, CmdArgs, RT, true, false);
3162*67e74705SXin Li   for (auto RT : HelperStaticRuntimes)
3163*67e74705SXin Li     addSanitizerRuntime(TC, Args, CmdArgs, RT, false, true);
3164*67e74705SXin Li   bool AddExportDynamic = false;
3165*67e74705SXin Li   for (auto RT : StaticRuntimes) {
3166*67e74705SXin Li     addSanitizerRuntime(TC, Args, CmdArgs, RT, false, true);
3167*67e74705SXin Li     AddExportDynamic |= !addSanitizerDynamicList(TC, Args, CmdArgs, RT);
3168*67e74705SXin Li   }
3169*67e74705SXin Li   for (auto RT : NonWholeStaticRuntimes) {
3170*67e74705SXin Li     addSanitizerRuntime(TC, Args, CmdArgs, RT, false, false);
3171*67e74705SXin Li     AddExportDynamic |= !addSanitizerDynamicList(TC, Args, CmdArgs, RT);
3172*67e74705SXin Li   }
3173*67e74705SXin Li   for (auto S : RequiredSymbols) {
3174*67e74705SXin Li     CmdArgs.push_back("-u");
3175*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(S));
3176*67e74705SXin Li   }
3177*67e74705SXin Li   // If there is a static runtime with no dynamic list, force all the symbols
3178*67e74705SXin Li   // to be dynamic to be sure we export sanitizer interface functions.
3179*67e74705SXin Li   if (AddExportDynamic)
3180*67e74705SXin Li     CmdArgs.push_back("-export-dynamic");
3181*67e74705SXin Li   return !StaticRuntimes.empty();
3182*67e74705SXin Li }
3183*67e74705SXin Li 
addXRayRuntime(const ToolChain & TC,const ArgList & Args,ArgStringList & CmdArgs)3184*67e74705SXin Li static bool addXRayRuntime(const ToolChain &TC, const ArgList &Args,
3185*67e74705SXin Li                            ArgStringList &CmdArgs) {
3186*67e74705SXin Li   if (Args.hasFlag(options::OPT_fxray_instrument,
3187*67e74705SXin Li                    options::OPT_fnoxray_instrument, false)) {
3188*67e74705SXin Li     CmdArgs.push_back("-whole-archive");
3189*67e74705SXin Li     CmdArgs.push_back(TC.getCompilerRTArgString(Args, "xray", false));
3190*67e74705SXin Li     CmdArgs.push_back("-no-whole-archive");
3191*67e74705SXin Li     return true;
3192*67e74705SXin Li   }
3193*67e74705SXin Li   return false;
3194*67e74705SXin Li }
3195*67e74705SXin Li 
linkXRayRuntimeDeps(const ToolChain & TC,const ArgList & Args,ArgStringList & CmdArgs)3196*67e74705SXin Li static void linkXRayRuntimeDeps(const ToolChain &TC, const ArgList &Args,
3197*67e74705SXin Li                                 ArgStringList &CmdArgs) {
3198*67e74705SXin Li   CmdArgs.push_back("--no-as-needed");
3199*67e74705SXin Li   CmdArgs.push_back("-lpthread");
3200*67e74705SXin Li   CmdArgs.push_back("-lrt");
3201*67e74705SXin Li   CmdArgs.push_back("-lm");
3202*67e74705SXin Li   CmdArgs.push_back("-latomic");
3203*67e74705SXin Li   if (TC.GetCXXStdlibType(Args) == ToolChain::CST_Libcxx)
3204*67e74705SXin Li     CmdArgs.push_back("-lc++");
3205*67e74705SXin Li   else
3206*67e74705SXin Li     CmdArgs.push_back("-lstdc++");
3207*67e74705SXin Li   if (TC.getTriple().getOS() != llvm::Triple::FreeBSD)
3208*67e74705SXin Li     CmdArgs.push_back("-ldl");
3209*67e74705SXin Li }
3210*67e74705SXin Li 
areOptimizationsEnabled(const ArgList & Args)3211*67e74705SXin Li static bool areOptimizationsEnabled(const ArgList &Args) {
3212*67e74705SXin Li   // Find the last -O arg and see if it is non-zero.
3213*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_O_Group))
3214*67e74705SXin Li     return !A->getOption().matches(options::OPT_O0);
3215*67e74705SXin Li   // Defaults to -O0.
3216*67e74705SXin Li   return false;
3217*67e74705SXin Li }
3218*67e74705SXin Li 
shouldUseFramePointerForTarget(const ArgList & Args,const llvm::Triple & Triple)3219*67e74705SXin Li static bool shouldUseFramePointerForTarget(const ArgList &Args,
3220*67e74705SXin Li                                            const llvm::Triple &Triple) {
3221*67e74705SXin Li   switch (Triple.getArch()) {
3222*67e74705SXin Li   case llvm::Triple::xcore:
3223*67e74705SXin Li   case llvm::Triple::wasm32:
3224*67e74705SXin Li   case llvm::Triple::wasm64:
3225*67e74705SXin Li     // XCore never wants frame pointers, regardless of OS.
3226*67e74705SXin Li     // WebAssembly never wants frame pointers.
3227*67e74705SXin Li     return false;
3228*67e74705SXin Li   default:
3229*67e74705SXin Li     break;
3230*67e74705SXin Li   }
3231*67e74705SXin Li 
3232*67e74705SXin Li   if (Triple.isOSLinux()) {
3233*67e74705SXin Li     switch (Triple.getArch()) {
3234*67e74705SXin Li     // Don't use a frame pointer on linux if optimizing for certain targets.
3235*67e74705SXin Li     case llvm::Triple::mips64:
3236*67e74705SXin Li     case llvm::Triple::mips64el:
3237*67e74705SXin Li     case llvm::Triple::mips:
3238*67e74705SXin Li     case llvm::Triple::mipsel:
3239*67e74705SXin Li     case llvm::Triple::systemz:
3240*67e74705SXin Li     case llvm::Triple::x86:
3241*67e74705SXin Li     case llvm::Triple::x86_64:
3242*67e74705SXin Li       return !areOptimizationsEnabled(Args);
3243*67e74705SXin Li     default:
3244*67e74705SXin Li       return true;
3245*67e74705SXin Li     }
3246*67e74705SXin Li   }
3247*67e74705SXin Li 
3248*67e74705SXin Li   if (Triple.isOSWindows()) {
3249*67e74705SXin Li     switch (Triple.getArch()) {
3250*67e74705SXin Li     case llvm::Triple::x86:
3251*67e74705SXin Li       return !areOptimizationsEnabled(Args);
3252*67e74705SXin Li     case llvm::Triple::x86_64:
3253*67e74705SXin Li       return Triple.isOSBinFormatMachO();
3254*67e74705SXin Li     case llvm::Triple::arm:
3255*67e74705SXin Li     case llvm::Triple::thumb:
3256*67e74705SXin Li       // Windows on ARM builds with FPO disabled to aid fast stack walking
3257*67e74705SXin Li       return true;
3258*67e74705SXin Li     default:
3259*67e74705SXin Li       // All other supported Windows ISAs use xdata unwind information, so frame
3260*67e74705SXin Li       // pointers are not generally useful.
3261*67e74705SXin Li       return false;
3262*67e74705SXin Li     }
3263*67e74705SXin Li   }
3264*67e74705SXin Li 
3265*67e74705SXin Li   return true;
3266*67e74705SXin Li }
3267*67e74705SXin Li 
shouldUseFramePointer(const ArgList & Args,const llvm::Triple & Triple)3268*67e74705SXin Li static bool shouldUseFramePointer(const ArgList &Args,
3269*67e74705SXin Li                                   const llvm::Triple &Triple) {
3270*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_fno_omit_frame_pointer,
3271*67e74705SXin Li                                options::OPT_fomit_frame_pointer))
3272*67e74705SXin Li     return A->getOption().matches(options::OPT_fno_omit_frame_pointer);
3273*67e74705SXin Li   if (Args.hasArg(options::OPT_pg))
3274*67e74705SXin Li     return true;
3275*67e74705SXin Li 
3276*67e74705SXin Li   return shouldUseFramePointerForTarget(Args, Triple);
3277*67e74705SXin Li }
3278*67e74705SXin Li 
shouldUseLeafFramePointer(const ArgList & Args,const llvm::Triple & Triple)3279*67e74705SXin Li static bool shouldUseLeafFramePointer(const ArgList &Args,
3280*67e74705SXin Li                                       const llvm::Triple &Triple) {
3281*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_mno_omit_leaf_frame_pointer,
3282*67e74705SXin Li                                options::OPT_momit_leaf_frame_pointer))
3283*67e74705SXin Li     return A->getOption().matches(options::OPT_mno_omit_leaf_frame_pointer);
3284*67e74705SXin Li   if (Args.hasArg(options::OPT_pg))
3285*67e74705SXin Li     return true;
3286*67e74705SXin Li 
3287*67e74705SXin Li   if (Triple.isPS4CPU())
3288*67e74705SXin Li     return false;
3289*67e74705SXin Li 
3290*67e74705SXin Li   return shouldUseFramePointerForTarget(Args, Triple);
3291*67e74705SXin Li }
3292*67e74705SXin Li 
3293*67e74705SXin Li /// Add a CC1 option to specify the debug compilation directory.
addDebugCompDirArg(const ArgList & Args,ArgStringList & CmdArgs)3294*67e74705SXin Li static void addDebugCompDirArg(const ArgList &Args, ArgStringList &CmdArgs) {
3295*67e74705SXin Li   SmallString<128> cwd;
3296*67e74705SXin Li   if (!llvm::sys::fs::current_path(cwd)) {
3297*67e74705SXin Li     CmdArgs.push_back("-fdebug-compilation-dir");
3298*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(cwd));
3299*67e74705SXin Li   }
3300*67e74705SXin Li }
3301*67e74705SXin Li 
SplitDebugName(const ArgList & Args,const InputInfo & Input)3302*67e74705SXin Li static const char *SplitDebugName(const ArgList &Args, const InputInfo &Input) {
3303*67e74705SXin Li   Arg *FinalOutput = Args.getLastArg(options::OPT_o);
3304*67e74705SXin Li   if (FinalOutput && Args.hasArg(options::OPT_c)) {
3305*67e74705SXin Li     SmallString<128> T(FinalOutput->getValue());
3306*67e74705SXin Li     llvm::sys::path::replace_extension(T, "dwo");
3307*67e74705SXin Li     return Args.MakeArgString(T);
3308*67e74705SXin Li   } else {
3309*67e74705SXin Li     // Use the compilation dir.
3310*67e74705SXin Li     SmallString<128> T(
3311*67e74705SXin Li         Args.getLastArgValue(options::OPT_fdebug_compilation_dir));
3312*67e74705SXin Li     SmallString<128> F(llvm::sys::path::stem(Input.getBaseInput()));
3313*67e74705SXin Li     llvm::sys::path::replace_extension(F, "dwo");
3314*67e74705SXin Li     T += F;
3315*67e74705SXin Li     return Args.MakeArgString(F);
3316*67e74705SXin Li   }
3317*67e74705SXin Li }
3318*67e74705SXin Li 
SplitDebugInfo(const ToolChain & TC,Compilation & C,const Tool & T,const JobAction & JA,const ArgList & Args,const InputInfo & Output,const char * OutFile)3319*67e74705SXin Li static void SplitDebugInfo(const ToolChain &TC, Compilation &C, const Tool &T,
3320*67e74705SXin Li                            const JobAction &JA, const ArgList &Args,
3321*67e74705SXin Li                            const InputInfo &Output, const char *OutFile) {
3322*67e74705SXin Li   ArgStringList ExtractArgs;
3323*67e74705SXin Li   ExtractArgs.push_back("--extract-dwo");
3324*67e74705SXin Li 
3325*67e74705SXin Li   ArgStringList StripArgs;
3326*67e74705SXin Li   StripArgs.push_back("--strip-dwo");
3327*67e74705SXin Li 
3328*67e74705SXin Li   // Grabbing the output of the earlier compile step.
3329*67e74705SXin Li   StripArgs.push_back(Output.getFilename());
3330*67e74705SXin Li   ExtractArgs.push_back(Output.getFilename());
3331*67e74705SXin Li   ExtractArgs.push_back(OutFile);
3332*67e74705SXin Li 
3333*67e74705SXin Li   const char *Exec = Args.MakeArgString(TC.GetProgramPath("objcopy"));
3334*67e74705SXin Li   InputInfo II(types::TY_Object, Output.getFilename(), Output.getFilename());
3335*67e74705SXin Li 
3336*67e74705SXin Li   // First extract the dwo sections.
3337*67e74705SXin Li   C.addCommand(llvm::make_unique<Command>(JA, T, Exec, ExtractArgs, II));
3338*67e74705SXin Li 
3339*67e74705SXin Li   // Then remove them from the original .o file.
3340*67e74705SXin Li   C.addCommand(llvm::make_unique<Command>(JA, T, Exec, StripArgs, II));
3341*67e74705SXin Li }
3342*67e74705SXin Li 
3343*67e74705SXin Li /// \brief Vectorize at all optimization levels greater than 1 except for -Oz.
3344*67e74705SXin Li /// For -Oz the loop vectorizer is disable, while the slp vectorizer is enabled.
shouldEnableVectorizerAtOLevel(const ArgList & Args,bool isSlpVec)3345*67e74705SXin Li static bool shouldEnableVectorizerAtOLevel(const ArgList &Args, bool isSlpVec) {
3346*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
3347*67e74705SXin Li     if (A->getOption().matches(options::OPT_O4) ||
3348*67e74705SXin Li         A->getOption().matches(options::OPT_Ofast))
3349*67e74705SXin Li       return true;
3350*67e74705SXin Li 
3351*67e74705SXin Li     if (A->getOption().matches(options::OPT_O0))
3352*67e74705SXin Li       return false;
3353*67e74705SXin Li 
3354*67e74705SXin Li     assert(A->getOption().matches(options::OPT_O) && "Must have a -O flag");
3355*67e74705SXin Li 
3356*67e74705SXin Li     // Vectorize -Os.
3357*67e74705SXin Li     StringRef S(A->getValue());
3358*67e74705SXin Li     if (S == "s")
3359*67e74705SXin Li       return true;
3360*67e74705SXin Li 
3361*67e74705SXin Li     // Don't vectorize -Oz, unless it's the slp vectorizer.
3362*67e74705SXin Li     if (S == "z")
3363*67e74705SXin Li       return isSlpVec;
3364*67e74705SXin Li 
3365*67e74705SXin Li     unsigned OptLevel = 0;
3366*67e74705SXin Li     if (S.getAsInteger(10, OptLevel))
3367*67e74705SXin Li       return false;
3368*67e74705SXin Li 
3369*67e74705SXin Li     return OptLevel > 1;
3370*67e74705SXin Li   }
3371*67e74705SXin Li 
3372*67e74705SXin Li   return false;
3373*67e74705SXin Li }
3374*67e74705SXin Li 
3375*67e74705SXin Li /// Add -x lang to \p CmdArgs for \p Input.
addDashXForInput(const ArgList & Args,const InputInfo & Input,ArgStringList & CmdArgs)3376*67e74705SXin Li static void addDashXForInput(const ArgList &Args, const InputInfo &Input,
3377*67e74705SXin Li                              ArgStringList &CmdArgs) {
3378*67e74705SXin Li   // When using -verify-pch, we don't want to provide the type
3379*67e74705SXin Li   // 'precompiled-header' if it was inferred from the file extension
3380*67e74705SXin Li   if (Args.hasArg(options::OPT_verify_pch) && Input.getType() == types::TY_PCH)
3381*67e74705SXin Li     return;
3382*67e74705SXin Li 
3383*67e74705SXin Li   CmdArgs.push_back("-x");
3384*67e74705SXin Li   if (Args.hasArg(options::OPT_rewrite_objc))
3385*67e74705SXin Li     CmdArgs.push_back(types::getTypeName(types::TY_PP_ObjCXX));
3386*67e74705SXin Li   else
3387*67e74705SXin Li     CmdArgs.push_back(types::getTypeName(Input.getType()));
3388*67e74705SXin Li }
3389*67e74705SXin Li 
getMSCompatibilityVersion(unsigned Version)3390*67e74705SXin Li static VersionTuple getMSCompatibilityVersion(unsigned Version) {
3391*67e74705SXin Li   if (Version < 100)
3392*67e74705SXin Li     return VersionTuple(Version);
3393*67e74705SXin Li 
3394*67e74705SXin Li   if (Version < 10000)
3395*67e74705SXin Li     return VersionTuple(Version / 100, Version % 100);
3396*67e74705SXin Li 
3397*67e74705SXin Li   unsigned Build = 0, Factor = 1;
3398*67e74705SXin Li   for (; Version > 10000; Version = Version / 10, Factor = Factor * 10)
3399*67e74705SXin Li     Build = Build + (Version % 10) * Factor;
3400*67e74705SXin Li   return VersionTuple(Version / 100, Version % 100, Build);
3401*67e74705SXin Li }
3402*67e74705SXin Li 
3403*67e74705SXin Li // Claim options we don't want to warn if they are unused. We do this for
3404*67e74705SXin Li // options that build systems might add but are unused when assembling or only
3405*67e74705SXin Li // running the preprocessor for example.
claimNoWarnArgs(const ArgList & Args)3406*67e74705SXin Li static void claimNoWarnArgs(const ArgList &Args) {
3407*67e74705SXin Li   // Don't warn about unused -f(no-)?lto.  This can happen when we're
3408*67e74705SXin Li   // preprocessing, precompiling or assembling.
3409*67e74705SXin Li   Args.ClaimAllArgs(options::OPT_flto_EQ);
3410*67e74705SXin Li   Args.ClaimAllArgs(options::OPT_flto);
3411*67e74705SXin Li   Args.ClaimAllArgs(options::OPT_fno_lto);
3412*67e74705SXin Li }
3413*67e74705SXin Li 
appendUserToPath(SmallVectorImpl<char> & Result)3414*67e74705SXin Li static void appendUserToPath(SmallVectorImpl<char> &Result) {
3415*67e74705SXin Li #ifdef LLVM_ON_UNIX
3416*67e74705SXin Li   const char *Username = getenv("LOGNAME");
3417*67e74705SXin Li #else
3418*67e74705SXin Li   const char *Username = getenv("USERNAME");
3419*67e74705SXin Li #endif
3420*67e74705SXin Li   if (Username) {
3421*67e74705SXin Li     // Validate that LoginName can be used in a path, and get its length.
3422*67e74705SXin Li     size_t Len = 0;
3423*67e74705SXin Li     for (const char *P = Username; *P; ++P, ++Len) {
3424*67e74705SXin Li       if (!isAlphanumeric(*P) && *P != '_') {
3425*67e74705SXin Li         Username = nullptr;
3426*67e74705SXin Li         break;
3427*67e74705SXin Li       }
3428*67e74705SXin Li     }
3429*67e74705SXin Li 
3430*67e74705SXin Li     if (Username && Len > 0) {
3431*67e74705SXin Li       Result.append(Username, Username + Len);
3432*67e74705SXin Li       return;
3433*67e74705SXin Li     }
3434*67e74705SXin Li   }
3435*67e74705SXin Li 
3436*67e74705SXin Li // Fallback to user id.
3437*67e74705SXin Li #ifdef LLVM_ON_UNIX
3438*67e74705SXin Li   std::string UID = llvm::utostr(getuid());
3439*67e74705SXin Li #else
3440*67e74705SXin Li   // FIXME: Windows seems to have an 'SID' that might work.
3441*67e74705SXin Li   std::string UID = "9999";
3442*67e74705SXin Li #endif
3443*67e74705SXin Li   Result.append(UID.begin(), UID.end());
3444*67e74705SXin Li }
3445*67e74705SXin Li 
getMSVCVersion(const Driver * D,const ToolChain & TC,const llvm::Triple & Triple,const llvm::opt::ArgList & Args,bool IsWindowsMSVC)3446*67e74705SXin Li VersionTuple visualstudio::getMSVCVersion(const Driver *D, const ToolChain &TC,
3447*67e74705SXin Li                                           const llvm::Triple &Triple,
3448*67e74705SXin Li                                           const llvm::opt::ArgList &Args,
3449*67e74705SXin Li                                           bool IsWindowsMSVC) {
3450*67e74705SXin Li   if (Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions,
3451*67e74705SXin Li                    IsWindowsMSVC) ||
3452*67e74705SXin Li       Args.hasArg(options::OPT_fmsc_version) ||
3453*67e74705SXin Li       Args.hasArg(options::OPT_fms_compatibility_version)) {
3454*67e74705SXin Li     const Arg *MSCVersion = Args.getLastArg(options::OPT_fmsc_version);
3455*67e74705SXin Li     const Arg *MSCompatibilityVersion =
3456*67e74705SXin Li         Args.getLastArg(options::OPT_fms_compatibility_version);
3457*67e74705SXin Li 
3458*67e74705SXin Li     if (MSCVersion && MSCompatibilityVersion) {
3459*67e74705SXin Li       if (D)
3460*67e74705SXin Li         D->Diag(diag::err_drv_argument_not_allowed_with)
3461*67e74705SXin Li             << MSCVersion->getAsString(Args)
3462*67e74705SXin Li             << MSCompatibilityVersion->getAsString(Args);
3463*67e74705SXin Li       return VersionTuple();
3464*67e74705SXin Li     }
3465*67e74705SXin Li 
3466*67e74705SXin Li     if (MSCompatibilityVersion) {
3467*67e74705SXin Li       VersionTuple MSVT;
3468*67e74705SXin Li       if (MSVT.tryParse(MSCompatibilityVersion->getValue()) && D)
3469*67e74705SXin Li         D->Diag(diag::err_drv_invalid_value)
3470*67e74705SXin Li             << MSCompatibilityVersion->getAsString(Args)
3471*67e74705SXin Li             << MSCompatibilityVersion->getValue();
3472*67e74705SXin Li       return MSVT;
3473*67e74705SXin Li     }
3474*67e74705SXin Li 
3475*67e74705SXin Li     if (MSCVersion) {
3476*67e74705SXin Li       unsigned Version = 0;
3477*67e74705SXin Li       if (StringRef(MSCVersion->getValue()).getAsInteger(10, Version) && D)
3478*67e74705SXin Li         D->Diag(diag::err_drv_invalid_value) << MSCVersion->getAsString(Args)
3479*67e74705SXin Li                                              << MSCVersion->getValue();
3480*67e74705SXin Li       return getMSCompatibilityVersion(Version);
3481*67e74705SXin Li     }
3482*67e74705SXin Li 
3483*67e74705SXin Li     unsigned Major, Minor, Micro;
3484*67e74705SXin Li     Triple.getEnvironmentVersion(Major, Minor, Micro);
3485*67e74705SXin Li     if (Major || Minor || Micro)
3486*67e74705SXin Li       return VersionTuple(Major, Minor, Micro);
3487*67e74705SXin Li 
3488*67e74705SXin Li     if (IsWindowsMSVC) {
3489*67e74705SXin Li       VersionTuple MSVT = TC.getMSVCVersionFromExe();
3490*67e74705SXin Li       if (!MSVT.empty())
3491*67e74705SXin Li         return MSVT;
3492*67e74705SXin Li 
3493*67e74705SXin Li       // FIXME: Consider bumping this to 19 (MSVC2015) soon.
3494*67e74705SXin Li       return VersionTuple(18);
3495*67e74705SXin Li     }
3496*67e74705SXin Li   }
3497*67e74705SXin Li   return VersionTuple();
3498*67e74705SXin Li }
3499*67e74705SXin Li 
addPGOAndCoverageFlags(Compilation & C,const Driver & D,const InputInfo & Output,const ArgList & Args,ArgStringList & CmdArgs)3500*67e74705SXin Li static void addPGOAndCoverageFlags(Compilation &C, const Driver &D,
3501*67e74705SXin Li                                    const InputInfo &Output, const ArgList &Args,
3502*67e74705SXin Li                                    ArgStringList &CmdArgs) {
3503*67e74705SXin Li   auto *ProfileGenerateArg = Args.getLastArg(
3504*67e74705SXin Li       options::OPT_fprofile_instr_generate,
3505*67e74705SXin Li       options::OPT_fprofile_instr_generate_EQ, options::OPT_fprofile_generate,
3506*67e74705SXin Li       options::OPT_fprofile_generate_EQ,
3507*67e74705SXin Li       options::OPT_fno_profile_instr_generate);
3508*67e74705SXin Li   if (ProfileGenerateArg &&
3509*67e74705SXin Li       ProfileGenerateArg->getOption().matches(
3510*67e74705SXin Li           options::OPT_fno_profile_instr_generate))
3511*67e74705SXin Li     ProfileGenerateArg = nullptr;
3512*67e74705SXin Li 
3513*67e74705SXin Li   auto *ProfileUseArg = Args.getLastArg(
3514*67e74705SXin Li       options::OPT_fprofile_instr_use, options::OPT_fprofile_instr_use_EQ,
3515*67e74705SXin Li       options::OPT_fprofile_use, options::OPT_fprofile_use_EQ,
3516*67e74705SXin Li       options::OPT_fno_profile_instr_use);
3517*67e74705SXin Li   if (ProfileUseArg &&
3518*67e74705SXin Li       ProfileUseArg->getOption().matches(options::OPT_fno_profile_instr_use))
3519*67e74705SXin Li     ProfileUseArg = nullptr;
3520*67e74705SXin Li 
3521*67e74705SXin Li   if (ProfileGenerateArg && ProfileUseArg)
3522*67e74705SXin Li     D.Diag(diag::err_drv_argument_not_allowed_with)
3523*67e74705SXin Li         << ProfileGenerateArg->getSpelling() << ProfileUseArg->getSpelling();
3524*67e74705SXin Li 
3525*67e74705SXin Li   if (ProfileGenerateArg) {
3526*67e74705SXin Li     if (ProfileGenerateArg->getOption().matches(
3527*67e74705SXin Li             options::OPT_fprofile_instr_generate_EQ))
3528*67e74705SXin Li       CmdArgs.push_back(Args.MakeArgString(Twine("-fprofile-instrument-path=") +
3529*67e74705SXin Li                                            ProfileGenerateArg->getValue()));
3530*67e74705SXin Li     else if (ProfileGenerateArg->getOption().matches(
3531*67e74705SXin Li                  options::OPT_fprofile_generate_EQ)) {
3532*67e74705SXin Li       SmallString<128> Path(ProfileGenerateArg->getValue());
3533*67e74705SXin Li       llvm::sys::path::append(Path, "default.profraw");
3534*67e74705SXin Li       CmdArgs.push_back(
3535*67e74705SXin Li           Args.MakeArgString(Twine("-fprofile-instrument-path=") + Path));
3536*67e74705SXin Li     }
3537*67e74705SXin Li     // The default is to use Clang Instrumentation.
3538*67e74705SXin Li     CmdArgs.push_back("-fprofile-instrument=clang");
3539*67e74705SXin Li   }
3540*67e74705SXin Li 
3541*67e74705SXin Li   if (ProfileUseArg) {
3542*67e74705SXin Li     if (ProfileUseArg->getOption().matches(options::OPT_fprofile_instr_use_EQ))
3543*67e74705SXin Li       CmdArgs.push_back(Args.MakeArgString(
3544*67e74705SXin Li           Twine("-fprofile-instrument-use-path=") + ProfileUseArg->getValue()));
3545*67e74705SXin Li     else if ((ProfileUseArg->getOption().matches(
3546*67e74705SXin Li                   options::OPT_fprofile_use_EQ) ||
3547*67e74705SXin Li               ProfileUseArg->getOption().matches(
3548*67e74705SXin Li                   options::OPT_fprofile_instr_use))) {
3549*67e74705SXin Li       SmallString<128> Path(
3550*67e74705SXin Li           ProfileUseArg->getNumValues() == 0 ? "" : ProfileUseArg->getValue());
3551*67e74705SXin Li       if (Path.empty() || llvm::sys::fs::is_directory(Path))
3552*67e74705SXin Li         llvm::sys::path::append(Path, "default.profdata");
3553*67e74705SXin Li       CmdArgs.push_back(
3554*67e74705SXin Li           Args.MakeArgString(Twine("-fprofile-instrument-use-path=") + Path));
3555*67e74705SXin Li     }
3556*67e74705SXin Li   }
3557*67e74705SXin Li 
3558*67e74705SXin Li   if (Args.hasArg(options::OPT_ftest_coverage) ||
3559*67e74705SXin Li       Args.hasArg(options::OPT_coverage))
3560*67e74705SXin Li     CmdArgs.push_back("-femit-coverage-notes");
3561*67e74705SXin Li   if (Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs,
3562*67e74705SXin Li                    false) ||
3563*67e74705SXin Li       Args.hasArg(options::OPT_coverage))
3564*67e74705SXin Li     CmdArgs.push_back("-femit-coverage-data");
3565*67e74705SXin Li 
3566*67e74705SXin Li   if (Args.hasFlag(options::OPT_fcoverage_mapping,
3567*67e74705SXin Li                    options::OPT_fno_coverage_mapping, false) &&
3568*67e74705SXin Li       !ProfileGenerateArg)
3569*67e74705SXin Li     D.Diag(diag::err_drv_argument_only_allowed_with)
3570*67e74705SXin Li         << "-fcoverage-mapping"
3571*67e74705SXin Li         << "-fprofile-instr-generate";
3572*67e74705SXin Li 
3573*67e74705SXin Li   if (Args.hasFlag(options::OPT_fcoverage_mapping,
3574*67e74705SXin Li                    options::OPT_fno_coverage_mapping, false))
3575*67e74705SXin Li     CmdArgs.push_back("-fcoverage-mapping");
3576*67e74705SXin Li 
3577*67e74705SXin Li   if (C.getArgs().hasArg(options::OPT_c) ||
3578*67e74705SXin Li       C.getArgs().hasArg(options::OPT_S)) {
3579*67e74705SXin Li     if (Output.isFilename()) {
3580*67e74705SXin Li       CmdArgs.push_back("-coverage-file");
3581*67e74705SXin Li       SmallString<128> CoverageFilename;
3582*67e74705SXin Li       if (Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o)) {
3583*67e74705SXin Li         CoverageFilename = FinalOutput->getValue();
3584*67e74705SXin Li       } else {
3585*67e74705SXin Li         CoverageFilename = llvm::sys::path::filename(Output.getBaseInput());
3586*67e74705SXin Li       }
3587*67e74705SXin Li       if (llvm::sys::path::is_relative(CoverageFilename)) {
3588*67e74705SXin Li         SmallString<128> Pwd;
3589*67e74705SXin Li         if (!llvm::sys::fs::current_path(Pwd)) {
3590*67e74705SXin Li           llvm::sys::path::append(Pwd, CoverageFilename);
3591*67e74705SXin Li           CoverageFilename.swap(Pwd);
3592*67e74705SXin Li         }
3593*67e74705SXin Li       }
3594*67e74705SXin Li       CmdArgs.push_back(Args.MakeArgString(CoverageFilename));
3595*67e74705SXin Li     }
3596*67e74705SXin Li   }
3597*67e74705SXin Li }
3598*67e74705SXin Li 
addPS4ProfileRTArgs(const ToolChain & TC,const ArgList & Args,ArgStringList & CmdArgs)3599*67e74705SXin Li static void addPS4ProfileRTArgs(const ToolChain &TC, const ArgList &Args,
3600*67e74705SXin Li                                 ArgStringList &CmdArgs) {
3601*67e74705SXin Li   if ((Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs,
3602*67e74705SXin Li                     false) ||
3603*67e74705SXin Li        Args.hasFlag(options::OPT_fprofile_generate,
3604*67e74705SXin Li                     options::OPT_fno_profile_instr_generate, false) ||
3605*67e74705SXin Li        Args.hasFlag(options::OPT_fprofile_generate_EQ,
3606*67e74705SXin Li                     options::OPT_fno_profile_instr_generate, false) ||
3607*67e74705SXin Li        Args.hasFlag(options::OPT_fprofile_instr_generate,
3608*67e74705SXin Li                     options::OPT_fno_profile_instr_generate, false) ||
3609*67e74705SXin Li        Args.hasFlag(options::OPT_fprofile_instr_generate_EQ,
3610*67e74705SXin Li                     options::OPT_fno_profile_instr_generate, false) ||
3611*67e74705SXin Li        Args.hasArg(options::OPT_fcreate_profile) ||
3612*67e74705SXin Li        Args.hasArg(options::OPT_coverage)))
3613*67e74705SXin Li     CmdArgs.push_back("--dependent-lib=libclang_rt.profile-x86_64.a");
3614*67e74705SXin Li }
3615*67e74705SXin Li 
3616*67e74705SXin Li /// Parses the various -fpic/-fPIC/-fpie/-fPIE arguments.  Then,
3617*67e74705SXin Li /// smooshes them together with platform defaults, to decide whether
3618*67e74705SXin Li /// this compile should be using PIC mode or not. Returns a tuple of
3619*67e74705SXin Li /// (RelocationModel, PICLevel, IsPIE).
3620*67e74705SXin Li static std::tuple<llvm::Reloc::Model, unsigned, bool>
ParsePICArgs(const ToolChain & ToolChain,const llvm::Triple & Triple,const ArgList & Args)3621*67e74705SXin Li ParsePICArgs(const ToolChain &ToolChain, const llvm::Triple &Triple,
3622*67e74705SXin Li              const ArgList &Args) {
3623*67e74705SXin Li   // FIXME: why does this code...and so much everywhere else, use both
3624*67e74705SXin Li   // ToolChain.getTriple() and Triple?
3625*67e74705SXin Li   bool PIE = ToolChain.isPIEDefault();
3626*67e74705SXin Li   bool PIC = PIE || ToolChain.isPICDefault();
3627*67e74705SXin Li   // The Darwin/MachO default to use PIC does not apply when using -static.
3628*67e74705SXin Li   if (ToolChain.getTriple().isOSBinFormatMachO() &&
3629*67e74705SXin Li       Args.hasArg(options::OPT_static))
3630*67e74705SXin Li     PIE = PIC = false;
3631*67e74705SXin Li   bool IsPICLevelTwo = PIC;
3632*67e74705SXin Li 
3633*67e74705SXin Li   bool KernelOrKext =
3634*67e74705SXin Li       Args.hasArg(options::OPT_mkernel, options::OPT_fapple_kext);
3635*67e74705SXin Li 
3636*67e74705SXin Li   // Android-specific defaults for PIC/PIE
3637*67e74705SXin Li   if (ToolChain.getTriple().isAndroid()) {
3638*67e74705SXin Li     switch (ToolChain.getArch()) {
3639*67e74705SXin Li     case llvm::Triple::arm:
3640*67e74705SXin Li     case llvm::Triple::armeb:
3641*67e74705SXin Li     case llvm::Triple::thumb:
3642*67e74705SXin Li     case llvm::Triple::thumbeb:
3643*67e74705SXin Li     case llvm::Triple::aarch64:
3644*67e74705SXin Li     case llvm::Triple::mips:
3645*67e74705SXin Li     case llvm::Triple::mipsel:
3646*67e74705SXin Li     case llvm::Triple::mips64:
3647*67e74705SXin Li     case llvm::Triple::mips64el:
3648*67e74705SXin Li       PIC = true; // "-fpic"
3649*67e74705SXin Li       break;
3650*67e74705SXin Li 
3651*67e74705SXin Li     case llvm::Triple::x86:
3652*67e74705SXin Li     case llvm::Triple::x86_64:
3653*67e74705SXin Li       PIC = true; // "-fPIC"
3654*67e74705SXin Li       IsPICLevelTwo = true;
3655*67e74705SXin Li       break;
3656*67e74705SXin Li 
3657*67e74705SXin Li     default:
3658*67e74705SXin Li       break;
3659*67e74705SXin Li     }
3660*67e74705SXin Li   }
3661*67e74705SXin Li 
3662*67e74705SXin Li   // OpenBSD-specific defaults for PIE
3663*67e74705SXin Li   if (ToolChain.getTriple().getOS() == llvm::Triple::OpenBSD) {
3664*67e74705SXin Li     switch (ToolChain.getArch()) {
3665*67e74705SXin Li     case llvm::Triple::mips64:
3666*67e74705SXin Li     case llvm::Triple::mips64el:
3667*67e74705SXin Li     case llvm::Triple::sparcel:
3668*67e74705SXin Li     case llvm::Triple::x86:
3669*67e74705SXin Li     case llvm::Triple::x86_64:
3670*67e74705SXin Li       IsPICLevelTwo = false; // "-fpie"
3671*67e74705SXin Li       break;
3672*67e74705SXin Li 
3673*67e74705SXin Li     case llvm::Triple::ppc:
3674*67e74705SXin Li     case llvm::Triple::sparc:
3675*67e74705SXin Li     case llvm::Triple::sparcv9:
3676*67e74705SXin Li       IsPICLevelTwo = true; // "-fPIE"
3677*67e74705SXin Li       break;
3678*67e74705SXin Li 
3679*67e74705SXin Li     default:
3680*67e74705SXin Li       break;
3681*67e74705SXin Li     }
3682*67e74705SXin Li   }
3683*67e74705SXin Li 
3684*67e74705SXin Li   // The last argument relating to either PIC or PIE wins, and no
3685*67e74705SXin Li   // other argument is used. If the last argument is any flavor of the
3686*67e74705SXin Li   // '-fno-...' arguments, both PIC and PIE are disabled. Any PIE
3687*67e74705SXin Li   // option implicitly enables PIC at the same level.
3688*67e74705SXin Li   Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC,
3689*67e74705SXin Li                                     options::OPT_fpic, options::OPT_fno_pic,
3690*67e74705SXin Li                                     options::OPT_fPIE, options::OPT_fno_PIE,
3691*67e74705SXin Li                                     options::OPT_fpie, options::OPT_fno_pie);
3692*67e74705SXin Li   // Check whether the tool chain trumps the PIC-ness decision. If the PIC-ness
3693*67e74705SXin Li   // is forced, then neither PIC nor PIE flags will have no effect.
3694*67e74705SXin Li   if (!ToolChain.isPICDefaultForced()) {
3695*67e74705SXin Li     if (LastPICArg) {
3696*67e74705SXin Li       Option O = LastPICArg->getOption();
3697*67e74705SXin Li       if (O.matches(options::OPT_fPIC) || O.matches(options::OPT_fpic) ||
3698*67e74705SXin Li           O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie)) {
3699*67e74705SXin Li         PIE = O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie);
3700*67e74705SXin Li         PIC =
3701*67e74705SXin Li             PIE || O.matches(options::OPT_fPIC) || O.matches(options::OPT_fpic);
3702*67e74705SXin Li         IsPICLevelTwo =
3703*67e74705SXin Li             O.matches(options::OPT_fPIE) || O.matches(options::OPT_fPIC);
3704*67e74705SXin Li       } else {
3705*67e74705SXin Li         PIE = PIC = false;
3706*67e74705SXin Li         if (Triple.isPS4CPU()) {
3707*67e74705SXin Li           Arg *ModelArg = Args.getLastArg(options::OPT_mcmodel_EQ);
3708*67e74705SXin Li           StringRef Model = ModelArg ? ModelArg->getValue() : "";
3709*67e74705SXin Li           if (Model != "kernel") {
3710*67e74705SXin Li             PIC = true;
3711*67e74705SXin Li             ToolChain.getDriver().Diag(diag::warn_drv_ps4_force_pic)
3712*67e74705SXin Li                 << LastPICArg->getSpelling();
3713*67e74705SXin Li           }
3714*67e74705SXin Li         }
3715*67e74705SXin Li       }
3716*67e74705SXin Li     }
3717*67e74705SXin Li   }
3718*67e74705SXin Li 
3719*67e74705SXin Li   // Introduce a Darwin and PS4-specific hack. If the default is PIC, but the
3720*67e74705SXin Li   // PIC level would've been set to level 1, force it back to level 2 PIC
3721*67e74705SXin Li   // instead.
3722*67e74705SXin Li   if (PIC && (ToolChain.getTriple().isOSDarwin() || Triple.isPS4CPU()))
3723*67e74705SXin Li     IsPICLevelTwo |= ToolChain.isPICDefault();
3724*67e74705SXin Li 
3725*67e74705SXin Li   // This kernel flags are a trump-card: they will disable PIC/PIE
3726*67e74705SXin Li   // generation, independent of the argument order.
3727*67e74705SXin Li   if (KernelOrKext && ((!Triple.isiOS() || Triple.isOSVersionLT(6)) &&
3728*67e74705SXin Li                        !Triple.isWatchOS()))
3729*67e74705SXin Li     PIC = PIE = false;
3730*67e74705SXin Li 
3731*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_mdynamic_no_pic)) {
3732*67e74705SXin Li     // This is a very special mode. It trumps the other modes, almost no one
3733*67e74705SXin Li     // uses it, and it isn't even valid on any OS but Darwin.
3734*67e74705SXin Li     if (!ToolChain.getTriple().isOSDarwin())
3735*67e74705SXin Li       ToolChain.getDriver().Diag(diag::err_drv_unsupported_opt_for_target)
3736*67e74705SXin Li           << A->getSpelling() << ToolChain.getTriple().str();
3737*67e74705SXin Li 
3738*67e74705SXin Li     // FIXME: Warn when this flag trumps some other PIC or PIE flag.
3739*67e74705SXin Li 
3740*67e74705SXin Li     // Only a forced PIC mode can cause the actual compile to have PIC defines
3741*67e74705SXin Li     // etc., no flags are sufficient. This behavior was selected to closely
3742*67e74705SXin Li     // match that of llvm-gcc and Apple GCC before that.
3743*67e74705SXin Li     PIC = ToolChain.isPICDefault() && ToolChain.isPICDefaultForced();
3744*67e74705SXin Li 
3745*67e74705SXin Li     return std::make_tuple(llvm::Reloc::DynamicNoPIC, PIC ? 2 : 0, false);
3746*67e74705SXin Li   }
3747*67e74705SXin Li 
3748*67e74705SXin Li   if (PIC)
3749*67e74705SXin Li     return std::make_tuple(llvm::Reloc::PIC_, IsPICLevelTwo ? 2 : 1, PIE);
3750*67e74705SXin Li 
3751*67e74705SXin Li   return std::make_tuple(llvm::Reloc::Static, 0, false);
3752*67e74705SXin Li }
3753*67e74705SXin Li 
RelocationModelName(llvm::Reloc::Model Model)3754*67e74705SXin Li static const char *RelocationModelName(llvm::Reloc::Model Model) {
3755*67e74705SXin Li   switch (Model) {
3756*67e74705SXin Li   case llvm::Reloc::Static:
3757*67e74705SXin Li     return "static";
3758*67e74705SXin Li   case llvm::Reloc::PIC_:
3759*67e74705SXin Li     return "pic";
3760*67e74705SXin Li   case llvm::Reloc::DynamicNoPIC:
3761*67e74705SXin Li     return "dynamic-no-pic";
3762*67e74705SXin Li   }
3763*67e74705SXin Li   llvm_unreachable("Unknown Reloc::Model kind");
3764*67e74705SXin Li }
3765*67e74705SXin Li 
AddAssemblerKPIC(const ToolChain & ToolChain,const ArgList & Args,ArgStringList & CmdArgs)3766*67e74705SXin Li static void AddAssemblerKPIC(const ToolChain &ToolChain, const ArgList &Args,
3767*67e74705SXin Li                              ArgStringList &CmdArgs) {
3768*67e74705SXin Li   llvm::Reloc::Model RelocationModel;
3769*67e74705SXin Li   unsigned PICLevel;
3770*67e74705SXin Li   bool IsPIE;
3771*67e74705SXin Li   std::tie(RelocationModel, PICLevel, IsPIE) =
3772*67e74705SXin Li       ParsePICArgs(ToolChain, ToolChain.getTriple(), Args);
3773*67e74705SXin Li 
3774*67e74705SXin Li   if (RelocationModel != llvm::Reloc::Static)
3775*67e74705SXin Li     CmdArgs.push_back("-KPIC");
3776*67e74705SXin Li }
3777*67e74705SXin Li 
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const3778*67e74705SXin Li void Clang::ConstructJob(Compilation &C, const JobAction &JA,
3779*67e74705SXin Li                          const InputInfo &Output, const InputInfoList &Inputs,
3780*67e74705SXin Li                          const ArgList &Args, const char *LinkingOutput) const {
3781*67e74705SXin Li   std::string TripleStr = getToolChain().ComputeEffectiveClangTriple(Args);
3782*67e74705SXin Li   const llvm::Triple Triple(TripleStr);
3783*67e74705SXin Li 
3784*67e74705SXin Li   bool KernelOrKext =
3785*67e74705SXin Li       Args.hasArg(options::OPT_mkernel, options::OPT_fapple_kext);
3786*67e74705SXin Li   const Driver &D = getToolChain().getDriver();
3787*67e74705SXin Li   ArgStringList CmdArgs;
3788*67e74705SXin Li 
3789*67e74705SXin Li   bool IsWindowsGNU = getToolChain().getTriple().isWindowsGNUEnvironment();
3790*67e74705SXin Li   bool IsWindowsCygnus =
3791*67e74705SXin Li       getToolChain().getTriple().isWindowsCygwinEnvironment();
3792*67e74705SXin Li   bool IsWindowsMSVC = getToolChain().getTriple().isWindowsMSVCEnvironment();
3793*67e74705SXin Li   bool IsPS4CPU = getToolChain().getTriple().isPS4CPU();
3794*67e74705SXin Li   bool IsIAMCU = getToolChain().getTriple().isOSIAMCU();
3795*67e74705SXin Li 
3796*67e74705SXin Li   // Check number of inputs for sanity. We need at least one input.
3797*67e74705SXin Li   assert(Inputs.size() >= 1 && "Must have at least one input.");
3798*67e74705SXin Li   const InputInfo &Input = Inputs[0];
3799*67e74705SXin Li   // CUDA compilation may have multiple inputs (source file + results of
3800*67e74705SXin Li   // device-side compilations). All other jobs are expected to have exactly one
3801*67e74705SXin Li   // input.
3802*67e74705SXin Li   bool IsCuda = types::isCuda(Input.getType());
3803*67e74705SXin Li   assert((IsCuda || Inputs.size() == 1) && "Unable to handle multiple inputs.");
3804*67e74705SXin Li 
3805*67e74705SXin Li   // C++ is not supported for IAMCU.
3806*67e74705SXin Li   if (IsIAMCU && types::isCXX(Input.getType()))
3807*67e74705SXin Li     D.Diag(diag::err_drv_clang_unsupported) << "C++ for IAMCU";
3808*67e74705SXin Li 
3809*67e74705SXin Li   // Invoke ourselves in -cc1 mode.
3810*67e74705SXin Li   //
3811*67e74705SXin Li   // FIXME: Implement custom jobs for internal actions.
3812*67e74705SXin Li   CmdArgs.push_back("-cc1");
3813*67e74705SXin Li 
3814*67e74705SXin Li   // Add the "effective" target triple.
3815*67e74705SXin Li   CmdArgs.push_back("-triple");
3816*67e74705SXin Li   CmdArgs.push_back(Args.MakeArgString(TripleStr));
3817*67e74705SXin Li 
3818*67e74705SXin Li   const ToolChain *AuxToolChain = nullptr;
3819*67e74705SXin Li   if (IsCuda) {
3820*67e74705SXin Li     // FIXME: We need a (better) way to pass information about
3821*67e74705SXin Li     // particular compilation pass we're constructing here. For now we
3822*67e74705SXin Li     // can check which toolchain we're using and pick the other one to
3823*67e74705SXin Li     // extract the triple.
3824*67e74705SXin Li     if (&getToolChain() == C.getSingleOffloadToolChain<Action::OFK_Cuda>())
3825*67e74705SXin Li       AuxToolChain = C.getOffloadingHostToolChain();
3826*67e74705SXin Li     else if (&getToolChain() == C.getOffloadingHostToolChain())
3827*67e74705SXin Li       AuxToolChain = C.getSingleOffloadToolChain<Action::OFK_Cuda>();
3828*67e74705SXin Li     else
3829*67e74705SXin Li       llvm_unreachable("Can't figure out CUDA compilation mode.");
3830*67e74705SXin Li     assert(AuxToolChain != nullptr && "No aux toolchain.");
3831*67e74705SXin Li     CmdArgs.push_back("-aux-triple");
3832*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(AuxToolChain->getTriple().str()));
3833*67e74705SXin Li   }
3834*67e74705SXin Li 
3835*67e74705SXin Li   if (Triple.isOSWindows() && (Triple.getArch() == llvm::Triple::arm ||
3836*67e74705SXin Li                                Triple.getArch() == llvm::Triple::thumb)) {
3837*67e74705SXin Li     unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6;
3838*67e74705SXin Li     unsigned Version;
3839*67e74705SXin Li     Triple.getArchName().substr(Offset).getAsInteger(10, Version);
3840*67e74705SXin Li     if (Version < 7)
3841*67e74705SXin Li       D.Diag(diag::err_target_unsupported_arch) << Triple.getArchName()
3842*67e74705SXin Li                                                 << TripleStr;
3843*67e74705SXin Li   }
3844*67e74705SXin Li 
3845*67e74705SXin Li   // Push all default warning arguments that are specific to
3846*67e74705SXin Li   // the given target.  These come before user provided warning options
3847*67e74705SXin Li   // are provided.
3848*67e74705SXin Li   getToolChain().addClangWarningOptions(CmdArgs);
3849*67e74705SXin Li 
3850*67e74705SXin Li   // Select the appropriate action.
3851*67e74705SXin Li   RewriteKind rewriteKind = RK_None;
3852*67e74705SXin Li 
3853*67e74705SXin Li   if (isa<AnalyzeJobAction>(JA)) {
3854*67e74705SXin Li     assert(JA.getType() == types::TY_Plist && "Invalid output type.");
3855*67e74705SXin Li     CmdArgs.push_back("-analyze");
3856*67e74705SXin Li   } else if (isa<MigrateJobAction>(JA)) {
3857*67e74705SXin Li     CmdArgs.push_back("-migrate");
3858*67e74705SXin Li   } else if (isa<PreprocessJobAction>(JA)) {
3859*67e74705SXin Li     if (Output.getType() == types::TY_Dependencies)
3860*67e74705SXin Li       CmdArgs.push_back("-Eonly");
3861*67e74705SXin Li     else {
3862*67e74705SXin Li       CmdArgs.push_back("-E");
3863*67e74705SXin Li       if (Args.hasArg(options::OPT_rewrite_objc) &&
3864*67e74705SXin Li           !Args.hasArg(options::OPT_g_Group))
3865*67e74705SXin Li         CmdArgs.push_back("-P");
3866*67e74705SXin Li     }
3867*67e74705SXin Li   } else if (isa<AssembleJobAction>(JA)) {
3868*67e74705SXin Li     CmdArgs.push_back("-emit-obj");
3869*67e74705SXin Li 
3870*67e74705SXin Li     CollectArgsForIntegratedAssembler(C, Args, CmdArgs, D);
3871*67e74705SXin Li 
3872*67e74705SXin Li     // Also ignore explicit -force_cpusubtype_ALL option.
3873*67e74705SXin Li     (void)Args.hasArg(options::OPT_force__cpusubtype__ALL);
3874*67e74705SXin Li   } else if (isa<PrecompileJobAction>(JA)) {
3875*67e74705SXin Li     // Use PCH if the user requested it.
3876*67e74705SXin Li     bool UsePCH = D.CCCUsePCH;
3877*67e74705SXin Li 
3878*67e74705SXin Li     if (JA.getType() == types::TY_Nothing)
3879*67e74705SXin Li       CmdArgs.push_back("-fsyntax-only");
3880*67e74705SXin Li     else if (UsePCH)
3881*67e74705SXin Li       CmdArgs.push_back("-emit-pch");
3882*67e74705SXin Li     else
3883*67e74705SXin Li       CmdArgs.push_back("-emit-pth");
3884*67e74705SXin Li   } else if (isa<VerifyPCHJobAction>(JA)) {
3885*67e74705SXin Li     CmdArgs.push_back("-verify-pch");
3886*67e74705SXin Li   } else {
3887*67e74705SXin Li     assert((isa<CompileJobAction>(JA) || isa<BackendJobAction>(JA)) &&
3888*67e74705SXin Li            "Invalid action for clang tool.");
3889*67e74705SXin Li     if (JA.getType() == types::TY_Nothing) {
3890*67e74705SXin Li       CmdArgs.push_back("-fsyntax-only");
3891*67e74705SXin Li     } else if (JA.getType() == types::TY_LLVM_IR ||
3892*67e74705SXin Li                JA.getType() == types::TY_LTO_IR) {
3893*67e74705SXin Li       CmdArgs.push_back("-emit-llvm");
3894*67e74705SXin Li     } else if (JA.getType() == types::TY_LLVM_BC ||
3895*67e74705SXin Li                JA.getType() == types::TY_LTO_BC) {
3896*67e74705SXin Li       CmdArgs.push_back("-emit-llvm-bc");
3897*67e74705SXin Li     } else if (JA.getType() == types::TY_PP_Asm) {
3898*67e74705SXin Li       CmdArgs.push_back("-S");
3899*67e74705SXin Li     } else if (JA.getType() == types::TY_AST) {
3900*67e74705SXin Li       CmdArgs.push_back("-emit-pch");
3901*67e74705SXin Li     } else if (JA.getType() == types::TY_ModuleFile) {
3902*67e74705SXin Li       CmdArgs.push_back("-module-file-info");
3903*67e74705SXin Li     } else if (JA.getType() == types::TY_RewrittenObjC) {
3904*67e74705SXin Li       CmdArgs.push_back("-rewrite-objc");
3905*67e74705SXin Li       rewriteKind = RK_NonFragile;
3906*67e74705SXin Li     } else if (JA.getType() == types::TY_RewrittenLegacyObjC) {
3907*67e74705SXin Li       CmdArgs.push_back("-rewrite-objc");
3908*67e74705SXin Li       rewriteKind = RK_Fragile;
3909*67e74705SXin Li     } else {
3910*67e74705SXin Li       assert(JA.getType() == types::TY_PP_Asm && "Unexpected output type!");
3911*67e74705SXin Li     }
3912*67e74705SXin Li 
3913*67e74705SXin Li     // Preserve use-list order by default when emitting bitcode, so that
3914*67e74705SXin Li     // loading the bitcode up in 'opt' or 'llc' and running passes gives the
3915*67e74705SXin Li     // same result as running passes here.  For LTO, we don't need to preserve
3916*67e74705SXin Li     // the use-list order, since serialization to bitcode is part of the flow.
3917*67e74705SXin Li     if (JA.getType() == types::TY_LLVM_BC)
3918*67e74705SXin Li       CmdArgs.push_back("-emit-llvm-uselists");
3919*67e74705SXin Li 
3920*67e74705SXin Li     if (D.isUsingLTO())
3921*67e74705SXin Li       Args.AddLastArg(CmdArgs, options::OPT_flto, options::OPT_flto_EQ);
3922*67e74705SXin Li   }
3923*67e74705SXin Li 
3924*67e74705SXin Li   if (const Arg *A = Args.getLastArg(options::OPT_fthinlto_index_EQ)) {
3925*67e74705SXin Li     if (!types::isLLVMIR(Input.getType()))
3926*67e74705SXin Li       D.Diag(diag::err_drv_argument_only_allowed_with) << A->getAsString(Args)
3927*67e74705SXin Li                                                        << "-x ir";
3928*67e74705SXin Li     Args.AddLastArg(CmdArgs, options::OPT_fthinlto_index_EQ);
3929*67e74705SXin Li   }
3930*67e74705SXin Li 
3931*67e74705SXin Li   // Embed-bitcode option.
3932*67e74705SXin Li   if (C.getDriver().embedBitcodeEnabled() &&
3933*67e74705SXin Li       (isa<BackendJobAction>(JA) || isa<AssembleJobAction>(JA))) {
3934*67e74705SXin Li     // Add flags implied by -fembed-bitcode.
3935*67e74705SXin Li     Args.AddLastArg(CmdArgs, options::OPT_fembed_bitcode_EQ);
3936*67e74705SXin Li     // Disable all llvm IR level optimizations.
3937*67e74705SXin Li     CmdArgs.push_back("-disable-llvm-optzns");
3938*67e74705SXin Li   }
3939*67e74705SXin Li   if (C.getDriver().embedBitcodeMarkerOnly())
3940*67e74705SXin Li     CmdArgs.push_back("-fembed-bitcode=marker");
3941*67e74705SXin Li 
3942*67e74705SXin Li   // We normally speed up the clang process a bit by skipping destructors at
3943*67e74705SXin Li   // exit, but when we're generating diagnostics we can rely on some of the
3944*67e74705SXin Li   // cleanup.
3945*67e74705SXin Li   if (!C.isForDiagnostics())
3946*67e74705SXin Li     CmdArgs.push_back("-disable-free");
3947*67e74705SXin Li 
3948*67e74705SXin Li // Disable the verification pass in -asserts builds.
3949*67e74705SXin Li #ifdef NDEBUG
3950*67e74705SXin Li   CmdArgs.push_back("-disable-llvm-verifier");
3951*67e74705SXin Li   // Discard LLVM value names in -asserts builds.
3952*67e74705SXin Li   CmdArgs.push_back("-discard-value-names");
3953*67e74705SXin Li #endif
3954*67e74705SXin Li 
3955*67e74705SXin Li   // Set the main file name, so that debug info works even with
3956*67e74705SXin Li   // -save-temps.
3957*67e74705SXin Li   CmdArgs.push_back("-main-file-name");
3958*67e74705SXin Li   CmdArgs.push_back(getBaseInputName(Args, Input));
3959*67e74705SXin Li 
3960*67e74705SXin Li   // Some flags which affect the language (via preprocessor
3961*67e74705SXin Li   // defines).
3962*67e74705SXin Li   if (Args.hasArg(options::OPT_static))
3963*67e74705SXin Li     CmdArgs.push_back("-static-define");
3964*67e74705SXin Li 
3965*67e74705SXin Li   if (isa<AnalyzeJobAction>(JA)) {
3966*67e74705SXin Li     // Enable region store model by default.
3967*67e74705SXin Li     CmdArgs.push_back("-analyzer-store=region");
3968*67e74705SXin Li 
3969*67e74705SXin Li     // Treat blocks as analysis entry points.
3970*67e74705SXin Li     CmdArgs.push_back("-analyzer-opt-analyze-nested-blocks");
3971*67e74705SXin Li 
3972*67e74705SXin Li     CmdArgs.push_back("-analyzer-eagerly-assume");
3973*67e74705SXin Li 
3974*67e74705SXin Li     // Add default argument set.
3975*67e74705SXin Li     if (!Args.hasArg(options::OPT__analyzer_no_default_checks)) {
3976*67e74705SXin Li       CmdArgs.push_back("-analyzer-checker=core");
3977*67e74705SXin Li 
3978*67e74705SXin Li     if (!IsWindowsMSVC) {
3979*67e74705SXin Li       CmdArgs.push_back("-analyzer-checker=unix");
3980*67e74705SXin Li     } else {
3981*67e74705SXin Li       // Enable "unix" checkers that also work on Windows.
3982*67e74705SXin Li       CmdArgs.push_back("-analyzer-checker=unix.API");
3983*67e74705SXin Li       CmdArgs.push_back("-analyzer-checker=unix.Malloc");
3984*67e74705SXin Li       CmdArgs.push_back("-analyzer-checker=unix.MallocSizeof");
3985*67e74705SXin Li       CmdArgs.push_back("-analyzer-checker=unix.MismatchedDeallocator");
3986*67e74705SXin Li       CmdArgs.push_back("-analyzer-checker=unix.cstring.BadSizeArg");
3987*67e74705SXin Li       CmdArgs.push_back("-analyzer-checker=unix.cstring.NullArg");
3988*67e74705SXin Li     }
3989*67e74705SXin Li 
3990*67e74705SXin Li       // Disable some unix checkers for PS4.
3991*67e74705SXin Li       if (IsPS4CPU) {
3992*67e74705SXin Li         CmdArgs.push_back("-analyzer-disable-checker=unix.API");
3993*67e74705SXin Li         CmdArgs.push_back("-analyzer-disable-checker=unix.Vfork");
3994*67e74705SXin Li       }
3995*67e74705SXin Li 
3996*67e74705SXin Li       if (getToolChain().getTriple().getVendor() == llvm::Triple::Apple)
3997*67e74705SXin Li         CmdArgs.push_back("-analyzer-checker=osx");
3998*67e74705SXin Li 
3999*67e74705SXin Li       CmdArgs.push_back("-analyzer-checker=deadcode");
4000*67e74705SXin Li 
4001*67e74705SXin Li       if (types::isCXX(Input.getType()))
4002*67e74705SXin Li         CmdArgs.push_back("-analyzer-checker=cplusplus");
4003*67e74705SXin Li 
4004*67e74705SXin Li       if (!IsPS4CPU) {
4005*67e74705SXin Li         CmdArgs.push_back(
4006*67e74705SXin Li             "-analyzer-checker=security.insecureAPI.UncheckedReturn");
4007*67e74705SXin Li         CmdArgs.push_back("-analyzer-checker=security.insecureAPI.getpw");
4008*67e74705SXin Li         CmdArgs.push_back("-analyzer-checker=security.insecureAPI.gets");
4009*67e74705SXin Li         CmdArgs.push_back("-analyzer-checker=security.insecureAPI.mktemp");
4010*67e74705SXin Li         CmdArgs.push_back("-analyzer-checker=security.insecureAPI.mkstemp");
4011*67e74705SXin Li         CmdArgs.push_back("-analyzer-checker=security.insecureAPI.vfork");
4012*67e74705SXin Li       }
4013*67e74705SXin Li 
4014*67e74705SXin Li       // Default nullability checks.
4015*67e74705SXin Li       CmdArgs.push_back("-analyzer-checker=nullability.NullPassedToNonnull");
4016*67e74705SXin Li       CmdArgs.push_back(
4017*67e74705SXin Li           "-analyzer-checker=nullability.NullReturnedFromNonnull");
4018*67e74705SXin Li     }
4019*67e74705SXin Li 
4020*67e74705SXin Li     // Set the output format. The default is plist, for (lame) historical
4021*67e74705SXin Li     // reasons.
4022*67e74705SXin Li     CmdArgs.push_back("-analyzer-output");
4023*67e74705SXin Li     if (Arg *A = Args.getLastArg(options::OPT__analyzer_output))
4024*67e74705SXin Li       CmdArgs.push_back(A->getValue());
4025*67e74705SXin Li     else
4026*67e74705SXin Li       CmdArgs.push_back("plist");
4027*67e74705SXin Li 
4028*67e74705SXin Li     // Disable the presentation of standard compiler warnings when
4029*67e74705SXin Li     // using --analyze.  We only want to show static analyzer diagnostics
4030*67e74705SXin Li     // or frontend errors.
4031*67e74705SXin Li     CmdArgs.push_back("-w");
4032*67e74705SXin Li 
4033*67e74705SXin Li     // Add -Xanalyzer arguments when running as analyzer.
4034*67e74705SXin Li     Args.AddAllArgValues(CmdArgs, options::OPT_Xanalyzer);
4035*67e74705SXin Li   }
4036*67e74705SXin Li 
4037*67e74705SXin Li   CheckCodeGenerationOptions(D, Args);
4038*67e74705SXin Li 
4039*67e74705SXin Li   llvm::Reloc::Model RelocationModel;
4040*67e74705SXin Li   unsigned PICLevel;
4041*67e74705SXin Li   bool IsPIE;
4042*67e74705SXin Li   std::tie(RelocationModel, PICLevel, IsPIE) =
4043*67e74705SXin Li       ParsePICArgs(getToolChain(), Triple, Args);
4044*67e74705SXin Li 
4045*67e74705SXin Li   const char *RMName = RelocationModelName(RelocationModel);
4046*67e74705SXin Li   if (RMName) {
4047*67e74705SXin Li     CmdArgs.push_back("-mrelocation-model");
4048*67e74705SXin Li     CmdArgs.push_back(RMName);
4049*67e74705SXin Li   }
4050*67e74705SXin Li   if (PICLevel > 0) {
4051*67e74705SXin Li     CmdArgs.push_back("-pic-level");
4052*67e74705SXin Li     CmdArgs.push_back(PICLevel == 1 ? "1" : "2");
4053*67e74705SXin Li     if (IsPIE)
4054*67e74705SXin Li       CmdArgs.push_back("-pic-is-pie");
4055*67e74705SXin Li   }
4056*67e74705SXin Li 
4057*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_meabi)) {
4058*67e74705SXin Li     CmdArgs.push_back("-meabi");
4059*67e74705SXin Li     CmdArgs.push_back(A->getValue());
4060*67e74705SXin Li   }
4061*67e74705SXin Li 
4062*67e74705SXin Li   CmdArgs.push_back("-mthread-model");
4063*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_mthread_model))
4064*67e74705SXin Li     CmdArgs.push_back(A->getValue());
4065*67e74705SXin Li   else
4066*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(getToolChain().getThreadModel()));
4067*67e74705SXin Li 
4068*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_fveclib);
4069*67e74705SXin Li 
4070*67e74705SXin Li   if (!Args.hasFlag(options::OPT_fmerge_all_constants,
4071*67e74705SXin Li                     options::OPT_fno_merge_all_constants))
4072*67e74705SXin Li     CmdArgs.push_back("-fno-merge-all-constants");
4073*67e74705SXin Li 
4074*67e74705SXin Li   // LLVM Code Generator Options.
4075*67e74705SXin Li 
4076*67e74705SXin Li   if (Args.hasArg(options::OPT_frewrite_map_file) ||
4077*67e74705SXin Li       Args.hasArg(options::OPT_frewrite_map_file_EQ)) {
4078*67e74705SXin Li     for (const Arg *A : Args.filtered(options::OPT_frewrite_map_file,
4079*67e74705SXin Li                                       options::OPT_frewrite_map_file_EQ)) {
4080*67e74705SXin Li       CmdArgs.push_back("-frewrite-map-file");
4081*67e74705SXin Li       CmdArgs.push_back(A->getValue());
4082*67e74705SXin Li       A->claim();
4083*67e74705SXin Li     }
4084*67e74705SXin Li   }
4085*67e74705SXin Li 
4086*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_Wframe_larger_than_EQ)) {
4087*67e74705SXin Li     StringRef v = A->getValue();
4088*67e74705SXin Li     CmdArgs.push_back("-mllvm");
4089*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString("-warn-stack-size=" + v));
4090*67e74705SXin Li     A->claim();
4091*67e74705SXin Li   }
4092*67e74705SXin Li 
4093*67e74705SXin Li   if (!Args.hasFlag(options::OPT_fjump_tables, options::OPT_fno_jump_tables,
4094*67e74705SXin Li                     true))
4095*67e74705SXin Li     CmdArgs.push_back("-fno-jump-tables");
4096*67e74705SXin Li 
4097*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_mregparm_EQ)) {
4098*67e74705SXin Li     CmdArgs.push_back("-mregparm");
4099*67e74705SXin Li     CmdArgs.push_back(A->getValue());
4100*67e74705SXin Li   }
4101*67e74705SXin Li 
4102*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_fpcc_struct_return,
4103*67e74705SXin Li                                options::OPT_freg_struct_return)) {
4104*67e74705SXin Li     if (getToolChain().getArch() != llvm::Triple::x86) {
4105*67e74705SXin Li       D.Diag(diag::err_drv_unsupported_opt_for_target)
4106*67e74705SXin Li           << A->getSpelling() << getToolChain().getTriple().str();
4107*67e74705SXin Li     } else if (A->getOption().matches(options::OPT_fpcc_struct_return)) {
4108*67e74705SXin Li       CmdArgs.push_back("-fpcc-struct-return");
4109*67e74705SXin Li     } else {
4110*67e74705SXin Li       assert(A->getOption().matches(options::OPT_freg_struct_return));
4111*67e74705SXin Li       CmdArgs.push_back("-freg-struct-return");
4112*67e74705SXin Li     }
4113*67e74705SXin Li   }
4114*67e74705SXin Li 
4115*67e74705SXin Li   if (Args.hasFlag(options::OPT_mrtd, options::OPT_mno_rtd, false))
4116*67e74705SXin Li     CmdArgs.push_back("-fdefault-calling-conv=stdcall");
4117*67e74705SXin Li 
4118*67e74705SXin Li   if (shouldUseFramePointer(Args, getToolChain().getTriple()))
4119*67e74705SXin Li     CmdArgs.push_back("-mdisable-fp-elim");
4120*67e74705SXin Li   if (!Args.hasFlag(options::OPT_fzero_initialized_in_bss,
4121*67e74705SXin Li                     options::OPT_fno_zero_initialized_in_bss))
4122*67e74705SXin Li     CmdArgs.push_back("-mno-zero-initialized-in-bss");
4123*67e74705SXin Li 
4124*67e74705SXin Li   bool OFastEnabled = isOptimizationLevelFast(Args);
4125*67e74705SXin Li   // If -Ofast is the optimization level, then -fstrict-aliasing should be
4126*67e74705SXin Li   // enabled.  This alias option is being used to simplify the hasFlag logic.
4127*67e74705SXin Li   OptSpecifier StrictAliasingAliasOption =
4128*67e74705SXin Li       OFastEnabled ? options::OPT_Ofast : options::OPT_fstrict_aliasing;
4129*67e74705SXin Li   // We turn strict aliasing off by default if we're in CL mode, since MSVC
4130*67e74705SXin Li   // doesn't do any TBAA.
4131*67e74705SXin Li   bool TBAAOnByDefault = !getToolChain().getDriver().IsCLMode();
4132*67e74705SXin Li   if (!Args.hasFlag(options::OPT_fstrict_aliasing, StrictAliasingAliasOption,
4133*67e74705SXin Li                     options::OPT_fno_strict_aliasing, TBAAOnByDefault))
4134*67e74705SXin Li     CmdArgs.push_back("-relaxed-aliasing");
4135*67e74705SXin Li   if (!Args.hasFlag(options::OPT_fstruct_path_tbaa,
4136*67e74705SXin Li                     options::OPT_fno_struct_path_tbaa))
4137*67e74705SXin Li     CmdArgs.push_back("-no-struct-path-tbaa");
4138*67e74705SXin Li   if (Args.hasFlag(options::OPT_fstrict_enums, options::OPT_fno_strict_enums,
4139*67e74705SXin Li                    false))
4140*67e74705SXin Li     CmdArgs.push_back("-fstrict-enums");
4141*67e74705SXin Li   if (Args.hasFlag(options::OPT_fstrict_vtable_pointers,
4142*67e74705SXin Li                    options::OPT_fno_strict_vtable_pointers,
4143*67e74705SXin Li                    false))
4144*67e74705SXin Li     CmdArgs.push_back("-fstrict-vtable-pointers");
4145*67e74705SXin Li   if (!Args.hasFlag(options::OPT_foptimize_sibling_calls,
4146*67e74705SXin Li                     options::OPT_fno_optimize_sibling_calls))
4147*67e74705SXin Li     CmdArgs.push_back("-mdisable-tail-calls");
4148*67e74705SXin Li 
4149*67e74705SXin Li   // Handle segmented stacks.
4150*67e74705SXin Li   if (Args.hasArg(options::OPT_fsplit_stack))
4151*67e74705SXin Li     CmdArgs.push_back("-split-stacks");
4152*67e74705SXin Li 
4153*67e74705SXin Li   // If -Ofast is the optimization level, then -ffast-math should be enabled.
4154*67e74705SXin Li   // This alias option is being used to simplify the getLastArg logic.
4155*67e74705SXin Li   OptSpecifier FastMathAliasOption =
4156*67e74705SXin Li       OFastEnabled ? options::OPT_Ofast : options::OPT_ffast_math;
4157*67e74705SXin Li 
4158*67e74705SXin Li   // Handle various floating point optimization flags, mapping them to the
4159*67e74705SXin Li   // appropriate LLVM code generation flags. The pattern for all of these is to
4160*67e74705SXin Li   // default off the codegen optimizations, and if any flag enables them and no
4161*67e74705SXin Li   // flag disables them after the flag enabling them, enable the codegen
4162*67e74705SXin Li   // optimization. This is complicated by several "umbrella" flags.
4163*67e74705SXin Li   if (Arg *A = Args.getLastArg(
4164*67e74705SXin Li           options::OPT_ffast_math, FastMathAliasOption,
4165*67e74705SXin Li           options::OPT_fno_fast_math, options::OPT_ffinite_math_only,
4166*67e74705SXin Li           options::OPT_fno_finite_math_only, options::OPT_fhonor_infinities,
4167*67e74705SXin Li           options::OPT_fno_honor_infinities))
4168*67e74705SXin Li     if (A->getOption().getID() != options::OPT_fno_fast_math &&
4169*67e74705SXin Li         A->getOption().getID() != options::OPT_fno_finite_math_only &&
4170*67e74705SXin Li         A->getOption().getID() != options::OPT_fhonor_infinities)
4171*67e74705SXin Li       CmdArgs.push_back("-menable-no-infs");
4172*67e74705SXin Li   if (Arg *A = Args.getLastArg(
4173*67e74705SXin Li           options::OPT_ffast_math, FastMathAliasOption,
4174*67e74705SXin Li           options::OPT_fno_fast_math, options::OPT_ffinite_math_only,
4175*67e74705SXin Li           options::OPT_fno_finite_math_only, options::OPT_fhonor_nans,
4176*67e74705SXin Li           options::OPT_fno_honor_nans))
4177*67e74705SXin Li     if (A->getOption().getID() != options::OPT_fno_fast_math &&
4178*67e74705SXin Li         A->getOption().getID() != options::OPT_fno_finite_math_only &&
4179*67e74705SXin Li         A->getOption().getID() != options::OPT_fhonor_nans)
4180*67e74705SXin Li       CmdArgs.push_back("-menable-no-nans");
4181*67e74705SXin Li 
4182*67e74705SXin Li   // -fmath-errno is the default on some platforms, e.g. BSD-derived OSes.
4183*67e74705SXin Li   bool MathErrno = getToolChain().IsMathErrnoDefault();
4184*67e74705SXin Li   if (Arg *A =
4185*67e74705SXin Li           Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption,
4186*67e74705SXin Li                           options::OPT_fno_fast_math, options::OPT_fmath_errno,
4187*67e74705SXin Li                           options::OPT_fno_math_errno)) {
4188*67e74705SXin Li     // Turning on -ffast_math (with either flag) removes the need for MathErrno.
4189*67e74705SXin Li     // However, turning *off* -ffast_math merely restores the toolchain default
4190*67e74705SXin Li     // (which may be false).
4191*67e74705SXin Li     if (A->getOption().getID() == options::OPT_fno_math_errno ||
4192*67e74705SXin Li         A->getOption().getID() == options::OPT_ffast_math ||
4193*67e74705SXin Li         A->getOption().getID() == options::OPT_Ofast)
4194*67e74705SXin Li       MathErrno = false;
4195*67e74705SXin Li     else if (A->getOption().getID() == options::OPT_fmath_errno)
4196*67e74705SXin Li       MathErrno = true;
4197*67e74705SXin Li   }
4198*67e74705SXin Li   if (MathErrno)
4199*67e74705SXin Li     CmdArgs.push_back("-fmath-errno");
4200*67e74705SXin Li 
4201*67e74705SXin Li   // There are several flags which require disabling very specific
4202*67e74705SXin Li   // optimizations. Any of these being disabled forces us to turn off the
4203*67e74705SXin Li   // entire set of LLVM optimizations, so collect them through all the flag
4204*67e74705SXin Li   // madness.
4205*67e74705SXin Li   bool AssociativeMath = false;
4206*67e74705SXin Li   if (Arg *A = Args.getLastArg(
4207*67e74705SXin Li           options::OPT_ffast_math, FastMathAliasOption,
4208*67e74705SXin Li           options::OPT_fno_fast_math, options::OPT_funsafe_math_optimizations,
4209*67e74705SXin Li           options::OPT_fno_unsafe_math_optimizations,
4210*67e74705SXin Li           options::OPT_fassociative_math, options::OPT_fno_associative_math))
4211*67e74705SXin Li     if (A->getOption().getID() != options::OPT_fno_fast_math &&
4212*67e74705SXin Li         A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations &&
4213*67e74705SXin Li         A->getOption().getID() != options::OPT_fno_associative_math)
4214*67e74705SXin Li       AssociativeMath = true;
4215*67e74705SXin Li   bool ReciprocalMath = false;
4216*67e74705SXin Li   if (Arg *A = Args.getLastArg(
4217*67e74705SXin Li           options::OPT_ffast_math, FastMathAliasOption,
4218*67e74705SXin Li           options::OPT_fno_fast_math, options::OPT_funsafe_math_optimizations,
4219*67e74705SXin Li           options::OPT_fno_unsafe_math_optimizations,
4220*67e74705SXin Li           options::OPT_freciprocal_math, options::OPT_fno_reciprocal_math))
4221*67e74705SXin Li     if (A->getOption().getID() != options::OPT_fno_fast_math &&
4222*67e74705SXin Li         A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations &&
4223*67e74705SXin Li         A->getOption().getID() != options::OPT_fno_reciprocal_math)
4224*67e74705SXin Li       ReciprocalMath = true;
4225*67e74705SXin Li   bool SignedZeros = true;
4226*67e74705SXin Li   if (Arg *A = Args.getLastArg(
4227*67e74705SXin Li           options::OPT_ffast_math, FastMathAliasOption,
4228*67e74705SXin Li           options::OPT_fno_fast_math, options::OPT_funsafe_math_optimizations,
4229*67e74705SXin Li           options::OPT_fno_unsafe_math_optimizations,
4230*67e74705SXin Li           options::OPT_fsigned_zeros, options::OPT_fno_signed_zeros))
4231*67e74705SXin Li     if (A->getOption().getID() != options::OPT_fno_fast_math &&
4232*67e74705SXin Li         A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations &&
4233*67e74705SXin Li         A->getOption().getID() != options::OPT_fsigned_zeros)
4234*67e74705SXin Li       SignedZeros = false;
4235*67e74705SXin Li   bool TrappingMath = true;
4236*67e74705SXin Li   if (Arg *A = Args.getLastArg(
4237*67e74705SXin Li           options::OPT_ffast_math, FastMathAliasOption,
4238*67e74705SXin Li           options::OPT_fno_fast_math, options::OPT_funsafe_math_optimizations,
4239*67e74705SXin Li           options::OPT_fno_unsafe_math_optimizations,
4240*67e74705SXin Li           options::OPT_ftrapping_math, options::OPT_fno_trapping_math))
4241*67e74705SXin Li     if (A->getOption().getID() != options::OPT_fno_fast_math &&
4242*67e74705SXin Li         A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations &&
4243*67e74705SXin Li         A->getOption().getID() != options::OPT_ftrapping_math)
4244*67e74705SXin Li       TrappingMath = false;
4245*67e74705SXin Li   if (!MathErrno && AssociativeMath && ReciprocalMath && !SignedZeros &&
4246*67e74705SXin Li       !TrappingMath)
4247*67e74705SXin Li     CmdArgs.push_back("-menable-unsafe-fp-math");
4248*67e74705SXin Li 
4249*67e74705SXin Li   if (!SignedZeros)
4250*67e74705SXin Li     CmdArgs.push_back("-fno-signed-zeros");
4251*67e74705SXin Li 
4252*67e74705SXin Li   if (ReciprocalMath)
4253*67e74705SXin Li     CmdArgs.push_back("-freciprocal-math");
4254*67e74705SXin Li 
4255*67e74705SXin Li   // Validate and pass through -fp-contract option.
4256*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption,
4257*67e74705SXin Li                                options::OPT_fno_fast_math,
4258*67e74705SXin Li                                options::OPT_ffp_contract)) {
4259*67e74705SXin Li     if (A->getOption().getID() == options::OPT_ffp_contract) {
4260*67e74705SXin Li       StringRef Val = A->getValue();
4261*67e74705SXin Li       if (Val == "fast" || Val == "on" || Val == "off") {
4262*67e74705SXin Li         CmdArgs.push_back(Args.MakeArgString("-ffp-contract=" + Val));
4263*67e74705SXin Li       } else {
4264*67e74705SXin Li         D.Diag(diag::err_drv_unsupported_option_argument)
4265*67e74705SXin Li             << A->getOption().getName() << Val;
4266*67e74705SXin Li       }
4267*67e74705SXin Li     } else if (A->getOption().matches(options::OPT_ffast_math) ||
4268*67e74705SXin Li                (OFastEnabled && A->getOption().matches(options::OPT_Ofast))) {
4269*67e74705SXin Li       // If fast-math is set then set the fp-contract mode to fast.
4270*67e74705SXin Li       CmdArgs.push_back(Args.MakeArgString("-ffp-contract=fast"));
4271*67e74705SXin Li     }
4272*67e74705SXin Li   }
4273*67e74705SXin Li 
4274*67e74705SXin Li   ParseMRecip(getToolChain().getDriver(), Args, CmdArgs);
4275*67e74705SXin Li 
4276*67e74705SXin Li   // We separately look for the '-ffast-math' and '-ffinite-math-only' flags,
4277*67e74705SXin Li   // and if we find them, tell the frontend to provide the appropriate
4278*67e74705SXin Li   // preprocessor macros. This is distinct from enabling any optimizations as
4279*67e74705SXin Li   // these options induce language changes which must survive serialization
4280*67e74705SXin Li   // and deserialization, etc.
4281*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption,
4282*67e74705SXin Li                                options::OPT_fno_fast_math))
4283*67e74705SXin Li     if (!A->getOption().matches(options::OPT_fno_fast_math))
4284*67e74705SXin Li       CmdArgs.push_back("-ffast-math");
4285*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_ffinite_math_only,
4286*67e74705SXin Li                                options::OPT_fno_fast_math))
4287*67e74705SXin Li     if (A->getOption().matches(options::OPT_ffinite_math_only))
4288*67e74705SXin Li       CmdArgs.push_back("-ffinite-math-only");
4289*67e74705SXin Li 
4290*67e74705SXin Li   // Decide whether to use verbose asm. Verbose assembly is the default on
4291*67e74705SXin Li   // toolchains which have the integrated assembler on by default.
4292*67e74705SXin Li   bool IsIntegratedAssemblerDefault =
4293*67e74705SXin Li       getToolChain().IsIntegratedAssemblerDefault();
4294*67e74705SXin Li   if (Args.hasFlag(options::OPT_fverbose_asm, options::OPT_fno_verbose_asm,
4295*67e74705SXin Li                    IsIntegratedAssemblerDefault) ||
4296*67e74705SXin Li       Args.hasArg(options::OPT_dA))
4297*67e74705SXin Li     CmdArgs.push_back("-masm-verbose");
4298*67e74705SXin Li 
4299*67e74705SXin Li   if (!Args.hasFlag(options::OPT_fintegrated_as, options::OPT_fno_integrated_as,
4300*67e74705SXin Li                     IsIntegratedAssemblerDefault))
4301*67e74705SXin Li     CmdArgs.push_back("-no-integrated-as");
4302*67e74705SXin Li 
4303*67e74705SXin Li   if (Args.hasArg(options::OPT_fdebug_pass_structure)) {
4304*67e74705SXin Li     CmdArgs.push_back("-mdebug-pass");
4305*67e74705SXin Li     CmdArgs.push_back("Structure");
4306*67e74705SXin Li   }
4307*67e74705SXin Li   if (Args.hasArg(options::OPT_fdebug_pass_arguments)) {
4308*67e74705SXin Li     CmdArgs.push_back("-mdebug-pass");
4309*67e74705SXin Li     CmdArgs.push_back("Arguments");
4310*67e74705SXin Li   }
4311*67e74705SXin Li 
4312*67e74705SXin Li   // Enable -mconstructor-aliases except on darwin, where we have to work around
4313*67e74705SXin Li   // a linker bug (see <rdar://problem/7651567>), and CUDA device code, where
4314*67e74705SXin Li   // aliases aren't supported.
4315*67e74705SXin Li   if (!getToolChain().getTriple().isOSDarwin() &&
4316*67e74705SXin Li       !getToolChain().getTriple().isNVPTX())
4317*67e74705SXin Li     CmdArgs.push_back("-mconstructor-aliases");
4318*67e74705SXin Li 
4319*67e74705SXin Li   // Darwin's kernel doesn't support guard variables; just die if we
4320*67e74705SXin Li   // try to use them.
4321*67e74705SXin Li   if (KernelOrKext && getToolChain().getTriple().isOSDarwin())
4322*67e74705SXin Li     CmdArgs.push_back("-fforbid-guard-variables");
4323*67e74705SXin Li 
4324*67e74705SXin Li   if (Args.hasFlag(options::OPT_mms_bitfields, options::OPT_mno_ms_bitfields,
4325*67e74705SXin Li                    false)) {
4326*67e74705SXin Li     CmdArgs.push_back("-mms-bitfields");
4327*67e74705SXin Li   }
4328*67e74705SXin Li 
4329*67e74705SXin Li   // This is a coarse approximation of what llvm-gcc actually does, both
4330*67e74705SXin Li   // -fasynchronous-unwind-tables and -fnon-call-exceptions interact in more
4331*67e74705SXin Li   // complicated ways.
4332*67e74705SXin Li   bool AsynchronousUnwindTables =
4333*67e74705SXin Li       Args.hasFlag(options::OPT_fasynchronous_unwind_tables,
4334*67e74705SXin Li                    options::OPT_fno_asynchronous_unwind_tables,
4335*67e74705SXin Li                    (getToolChain().IsUnwindTablesDefault() ||
4336*67e74705SXin Li                     getToolChain().getSanitizerArgs().needsUnwindTables()) &&
4337*67e74705SXin Li                        !KernelOrKext);
4338*67e74705SXin Li   if (Args.hasFlag(options::OPT_funwind_tables, options::OPT_fno_unwind_tables,
4339*67e74705SXin Li                    AsynchronousUnwindTables))
4340*67e74705SXin Li     CmdArgs.push_back("-munwind-tables");
4341*67e74705SXin Li 
4342*67e74705SXin Li   getToolChain().addClangTargetOptions(Args, CmdArgs);
4343*67e74705SXin Li 
4344*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_flimited_precision_EQ)) {
4345*67e74705SXin Li     CmdArgs.push_back("-mlimit-float-precision");
4346*67e74705SXin Li     CmdArgs.push_back(A->getValue());
4347*67e74705SXin Li   }
4348*67e74705SXin Li 
4349*67e74705SXin Li   // FIXME: Handle -mtune=.
4350*67e74705SXin Li   (void)Args.hasArg(options::OPT_mtune_EQ);
4351*67e74705SXin Li 
4352*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_mcmodel_EQ)) {
4353*67e74705SXin Li     CmdArgs.push_back("-mcode-model");
4354*67e74705SXin Li     CmdArgs.push_back(A->getValue());
4355*67e74705SXin Li   }
4356*67e74705SXin Li 
4357*67e74705SXin Li   // Add the target cpu
4358*67e74705SXin Li   std::string CPU = getCPUName(Args, Triple, /*FromAs*/ false);
4359*67e74705SXin Li   if (!CPU.empty()) {
4360*67e74705SXin Li     CmdArgs.push_back("-target-cpu");
4361*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(CPU));
4362*67e74705SXin Li   }
4363*67e74705SXin Li 
4364*67e74705SXin Li   if (const Arg *A = Args.getLastArg(options::OPT_mfpmath_EQ)) {
4365*67e74705SXin Li     CmdArgs.push_back("-mfpmath");
4366*67e74705SXin Li     CmdArgs.push_back(A->getValue());
4367*67e74705SXin Li   }
4368*67e74705SXin Li 
4369*67e74705SXin Li   // Add the target features
4370*67e74705SXin Li   getTargetFeatures(getToolChain(), Triple, Args, CmdArgs, false);
4371*67e74705SXin Li 
4372*67e74705SXin Li   // Add target specific flags.
4373*67e74705SXin Li   switch (getToolChain().getArch()) {
4374*67e74705SXin Li   default:
4375*67e74705SXin Li     break;
4376*67e74705SXin Li 
4377*67e74705SXin Li   case llvm::Triple::arm:
4378*67e74705SXin Li   case llvm::Triple::armeb:
4379*67e74705SXin Li   case llvm::Triple::thumb:
4380*67e74705SXin Li   case llvm::Triple::thumbeb:
4381*67e74705SXin Li     // Use the effective triple, which takes into account the deployment target.
4382*67e74705SXin Li     AddARMTargetArgs(Triple, Args, CmdArgs, KernelOrKext);
4383*67e74705SXin Li     break;
4384*67e74705SXin Li 
4385*67e74705SXin Li   case llvm::Triple::aarch64:
4386*67e74705SXin Li   case llvm::Triple::aarch64_be:
4387*67e74705SXin Li     AddAArch64TargetArgs(Args, CmdArgs);
4388*67e74705SXin Li     break;
4389*67e74705SXin Li 
4390*67e74705SXin Li   case llvm::Triple::mips:
4391*67e74705SXin Li   case llvm::Triple::mipsel:
4392*67e74705SXin Li   case llvm::Triple::mips64:
4393*67e74705SXin Li   case llvm::Triple::mips64el:
4394*67e74705SXin Li     AddMIPSTargetArgs(Args, CmdArgs);
4395*67e74705SXin Li     break;
4396*67e74705SXin Li 
4397*67e74705SXin Li   case llvm::Triple::ppc:
4398*67e74705SXin Li   case llvm::Triple::ppc64:
4399*67e74705SXin Li   case llvm::Triple::ppc64le:
4400*67e74705SXin Li     AddPPCTargetArgs(Args, CmdArgs);
4401*67e74705SXin Li     break;
4402*67e74705SXin Li 
4403*67e74705SXin Li   case llvm::Triple::sparc:
4404*67e74705SXin Li   case llvm::Triple::sparcel:
4405*67e74705SXin Li   case llvm::Triple::sparcv9:
4406*67e74705SXin Li     AddSparcTargetArgs(Args, CmdArgs);
4407*67e74705SXin Li     break;
4408*67e74705SXin Li 
4409*67e74705SXin Li   case llvm::Triple::systemz:
4410*67e74705SXin Li     AddSystemZTargetArgs(Args, CmdArgs);
4411*67e74705SXin Li     break;
4412*67e74705SXin Li 
4413*67e74705SXin Li   case llvm::Triple::x86:
4414*67e74705SXin Li   case llvm::Triple::x86_64:
4415*67e74705SXin Li     AddX86TargetArgs(Args, CmdArgs);
4416*67e74705SXin Li     break;
4417*67e74705SXin Li 
4418*67e74705SXin Li   case llvm::Triple::lanai:
4419*67e74705SXin Li     AddLanaiTargetArgs(Args, CmdArgs);
4420*67e74705SXin Li     break;
4421*67e74705SXin Li 
4422*67e74705SXin Li   case llvm::Triple::hexagon:
4423*67e74705SXin Li     AddHexagonTargetArgs(Args, CmdArgs);
4424*67e74705SXin Li     break;
4425*67e74705SXin Li 
4426*67e74705SXin Li   case llvm::Triple::wasm32:
4427*67e74705SXin Li   case llvm::Triple::wasm64:
4428*67e74705SXin Li     AddWebAssemblyTargetArgs(Args, CmdArgs);
4429*67e74705SXin Li     break;
4430*67e74705SXin Li   }
4431*67e74705SXin Li 
4432*67e74705SXin Li   // The 'g' groups options involve a somewhat intricate sequence of decisions
4433*67e74705SXin Li   // about what to pass from the driver to the frontend, but by the time they
4434*67e74705SXin Li   // reach cc1 they've been factored into three well-defined orthogonal choices:
4435*67e74705SXin Li   //  * what level of debug info to generate
4436*67e74705SXin Li   //  * what dwarf version to write
4437*67e74705SXin Li   //  * what debugger tuning to use
4438*67e74705SXin Li   // This avoids having to monkey around further in cc1 other than to disable
4439*67e74705SXin Li   // codeview if not running in a Windows environment. Perhaps even that
4440*67e74705SXin Li   // decision should be made in the driver as well though.
4441*67e74705SXin Li   unsigned DwarfVersion = 0;
4442*67e74705SXin Li   llvm::DebuggerKind DebuggerTuning = getToolChain().getDefaultDebuggerTuning();
4443*67e74705SXin Li   // These two are potentially updated by AddClangCLArgs.
4444*67e74705SXin Li   codegenoptions::DebugInfoKind DebugInfoKind = codegenoptions::NoDebugInfo;
4445*67e74705SXin Li   bool EmitCodeView = false;
4446*67e74705SXin Li 
4447*67e74705SXin Li   // Add clang-cl arguments.
4448*67e74705SXin Li   types::ID InputType = Input.getType();
4449*67e74705SXin Li   if (getToolChain().getDriver().IsCLMode())
4450*67e74705SXin Li     AddClangCLArgs(Args, InputType, CmdArgs, &DebugInfoKind, &EmitCodeView);
4451*67e74705SXin Li 
4452*67e74705SXin Li   // Pass the linker version in use.
4453*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ)) {
4454*67e74705SXin Li     CmdArgs.push_back("-target-linker-version");
4455*67e74705SXin Li     CmdArgs.push_back(A->getValue());
4456*67e74705SXin Li   }
4457*67e74705SXin Li 
4458*67e74705SXin Li   if (!shouldUseLeafFramePointer(Args, getToolChain().getTriple()))
4459*67e74705SXin Li     CmdArgs.push_back("-momit-leaf-frame-pointer");
4460*67e74705SXin Li 
4461*67e74705SXin Li   // Explicitly error on some things we know we don't support and can't just
4462*67e74705SXin Li   // ignore.
4463*67e74705SXin Li   if (!Args.hasArg(options::OPT_fallow_unsupported)) {
4464*67e74705SXin Li     Arg *Unsupported;
4465*67e74705SXin Li     if (types::isCXX(InputType) && getToolChain().getTriple().isOSDarwin() &&
4466*67e74705SXin Li         getToolChain().getArch() == llvm::Triple::x86) {
4467*67e74705SXin Li       if ((Unsupported = Args.getLastArg(options::OPT_fapple_kext)) ||
4468*67e74705SXin Li           (Unsupported = Args.getLastArg(options::OPT_mkernel)))
4469*67e74705SXin Li         D.Diag(diag::err_drv_clang_unsupported_opt_cxx_darwin_i386)
4470*67e74705SXin Li             << Unsupported->getOption().getName();
4471*67e74705SXin Li     }
4472*67e74705SXin Li   }
4473*67e74705SXin Li 
4474*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_v);
4475*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_H);
4476*67e74705SXin Li   if (D.CCPrintHeaders && !D.CCGenDiagnostics) {
4477*67e74705SXin Li     CmdArgs.push_back("-header-include-file");
4478*67e74705SXin Li     CmdArgs.push_back(D.CCPrintHeadersFilename ? D.CCPrintHeadersFilename
4479*67e74705SXin Li                                                : "-");
4480*67e74705SXin Li   }
4481*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_P);
4482*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_print_ivar_layout);
4483*67e74705SXin Li 
4484*67e74705SXin Li   if (D.CCLogDiagnostics && !D.CCGenDiagnostics) {
4485*67e74705SXin Li     CmdArgs.push_back("-diagnostic-log-file");
4486*67e74705SXin Li     CmdArgs.push_back(D.CCLogDiagnosticsFilename ? D.CCLogDiagnosticsFilename
4487*67e74705SXin Li                                                  : "-");
4488*67e74705SXin Li   }
4489*67e74705SXin Li 
4490*67e74705SXin Li   Args.ClaimAllArgs(options::OPT_g_Group);
4491*67e74705SXin Li   Arg *SplitDwarfArg = Args.getLastArg(options::OPT_gsplit_dwarf);
4492*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_g_Group)) {
4493*67e74705SXin Li     // If the last option explicitly specified a debug-info level, use it.
4494*67e74705SXin Li     if (A->getOption().matches(options::OPT_gN_Group)) {
4495*67e74705SXin Li       DebugInfoKind = DebugLevelToInfoKind(*A);
4496*67e74705SXin Li       // If you say "-gsplit-dwarf -gline-tables-only", -gsplit-dwarf loses.
4497*67e74705SXin Li       // But -gsplit-dwarf is not a g_group option, hence we have to check the
4498*67e74705SXin Li       // order explicitly. (If -gsplit-dwarf wins, we fix DebugInfoKind later.)
4499*67e74705SXin Li       if (SplitDwarfArg && DebugInfoKind < codegenoptions::LimitedDebugInfo &&
4500*67e74705SXin Li           A->getIndex() > SplitDwarfArg->getIndex())
4501*67e74705SXin Li         SplitDwarfArg = nullptr;
4502*67e74705SXin Li     } else
4503*67e74705SXin Li       // For any other 'g' option, use Limited.
4504*67e74705SXin Li       DebugInfoKind = codegenoptions::LimitedDebugInfo;
4505*67e74705SXin Li   }
4506*67e74705SXin Li 
4507*67e74705SXin Li   // If a debugger tuning argument appeared, remember it.
4508*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_gTune_Group,
4509*67e74705SXin Li                                options::OPT_ggdbN_Group)) {
4510*67e74705SXin Li     if (A->getOption().matches(options::OPT_glldb))
4511*67e74705SXin Li       DebuggerTuning = llvm::DebuggerKind::LLDB;
4512*67e74705SXin Li     else if (A->getOption().matches(options::OPT_gsce))
4513*67e74705SXin Li       DebuggerTuning = llvm::DebuggerKind::SCE;
4514*67e74705SXin Li     else
4515*67e74705SXin Li       DebuggerTuning = llvm::DebuggerKind::GDB;
4516*67e74705SXin Li   }
4517*67e74705SXin Li 
4518*67e74705SXin Li   // If a -gdwarf argument appeared, remember it.
4519*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_gdwarf_2, options::OPT_gdwarf_3,
4520*67e74705SXin Li                                options::OPT_gdwarf_4, options::OPT_gdwarf_5))
4521*67e74705SXin Li     DwarfVersion = DwarfVersionNum(A->getSpelling());
4522*67e74705SXin Li 
4523*67e74705SXin Li   // Forward -gcodeview.
4524*67e74705SXin Li   // 'EmitCodeView might have been set by CL-compatibility argument parsing.
4525*67e74705SXin Li   if (Args.hasArg(options::OPT_gcodeview) || EmitCodeView) {
4526*67e74705SXin Li     // DwarfVersion remains at 0 if no explicit choice was made.
4527*67e74705SXin Li     CmdArgs.push_back("-gcodeview");
4528*67e74705SXin Li   } else if (DwarfVersion == 0 &&
4529*67e74705SXin Li              DebugInfoKind != codegenoptions::NoDebugInfo) {
4530*67e74705SXin Li     DwarfVersion = getToolChain().GetDefaultDwarfVersion();
4531*67e74705SXin Li   }
4532*67e74705SXin Li 
4533*67e74705SXin Li   // We ignore flags -gstrict-dwarf and -grecord-gcc-switches for now.
4534*67e74705SXin Li   Args.ClaimAllArgs(options::OPT_g_flags_Group);
4535*67e74705SXin Li 
4536*67e74705SXin Li   // PS4 defaults to no column info
4537*67e74705SXin Li   if (Args.hasFlag(options::OPT_gcolumn_info, options::OPT_gno_column_info,
4538*67e74705SXin Li                    /*Default=*/ !IsPS4CPU))
4539*67e74705SXin Li     CmdArgs.push_back("-dwarf-column-info");
4540*67e74705SXin Li 
4541*67e74705SXin Li   // FIXME: Move backend command line options to the module.
4542*67e74705SXin Li   if (Args.hasArg(options::OPT_gmodules)) {
4543*67e74705SXin Li     DebugInfoKind = codegenoptions::LimitedDebugInfo;
4544*67e74705SXin Li     CmdArgs.push_back("-dwarf-ext-refs");
4545*67e74705SXin Li     CmdArgs.push_back("-fmodule-format=obj");
4546*67e74705SXin Li   }
4547*67e74705SXin Li 
4548*67e74705SXin Li   // -gsplit-dwarf should turn on -g and enable the backend dwarf
4549*67e74705SXin Li   // splitting and extraction.
4550*67e74705SXin Li   // FIXME: Currently only works on Linux.
4551*67e74705SXin Li   if (getToolChain().getTriple().isOSLinux() && SplitDwarfArg) {
4552*67e74705SXin Li     DebugInfoKind = codegenoptions::LimitedDebugInfo;
4553*67e74705SXin Li     CmdArgs.push_back("-backend-option");
4554*67e74705SXin Li     CmdArgs.push_back("-split-dwarf=Enable");
4555*67e74705SXin Li   }
4556*67e74705SXin Li 
4557*67e74705SXin Li   // After we've dealt with all combinations of things that could
4558*67e74705SXin Li   // make DebugInfoKind be other than None or DebugLineTablesOnly,
4559*67e74705SXin Li   // figure out if we need to "upgrade" it to standalone debug info.
4560*67e74705SXin Li   // We parse these two '-f' options whether or not they will be used,
4561*67e74705SXin Li   // to claim them even if you wrote "-fstandalone-debug -gline-tables-only"
4562*67e74705SXin Li   bool NeedFullDebug = Args.hasFlag(options::OPT_fstandalone_debug,
4563*67e74705SXin Li                                     options::OPT_fno_standalone_debug,
4564*67e74705SXin Li                                     getToolChain().GetDefaultStandaloneDebug());
4565*67e74705SXin Li   if (DebugInfoKind == codegenoptions::LimitedDebugInfo && NeedFullDebug)
4566*67e74705SXin Li     DebugInfoKind = codegenoptions::FullDebugInfo;
4567*67e74705SXin Li   RenderDebugEnablingArgs(Args, CmdArgs, DebugInfoKind, DwarfVersion,
4568*67e74705SXin Li                           DebuggerTuning);
4569*67e74705SXin Li 
4570*67e74705SXin Li   // -ggnu-pubnames turns on gnu style pubnames in the backend.
4571*67e74705SXin Li   if (Args.hasArg(options::OPT_ggnu_pubnames)) {
4572*67e74705SXin Li     CmdArgs.push_back("-backend-option");
4573*67e74705SXin Li     CmdArgs.push_back("-generate-gnu-dwarf-pub-sections");
4574*67e74705SXin Li   }
4575*67e74705SXin Li 
4576*67e74705SXin Li   // -gdwarf-aranges turns on the emission of the aranges section in the
4577*67e74705SXin Li   // backend.
4578*67e74705SXin Li   // Always enabled on the PS4.
4579*67e74705SXin Li   if (Args.hasArg(options::OPT_gdwarf_aranges) || IsPS4CPU) {
4580*67e74705SXin Li     CmdArgs.push_back("-backend-option");
4581*67e74705SXin Li     CmdArgs.push_back("-generate-arange-section");
4582*67e74705SXin Li   }
4583*67e74705SXin Li 
4584*67e74705SXin Li   if (Args.hasFlag(options::OPT_fdebug_types_section,
4585*67e74705SXin Li                    options::OPT_fno_debug_types_section, false)) {
4586*67e74705SXin Li     CmdArgs.push_back("-backend-option");
4587*67e74705SXin Li     CmdArgs.push_back("-generate-type-units");
4588*67e74705SXin Li   }
4589*67e74705SXin Li 
4590*67e74705SXin Li   // CloudABI and WebAssembly use -ffunction-sections and -fdata-sections by
4591*67e74705SXin Li   // default.
4592*67e74705SXin Li   bool UseSeparateSections = Triple.getOS() == llvm::Triple::CloudABI ||
4593*67e74705SXin Li                              Triple.getArch() == llvm::Triple::wasm32 ||
4594*67e74705SXin Li                              Triple.getArch() == llvm::Triple::wasm64;
4595*67e74705SXin Li 
4596*67e74705SXin Li   if (Args.hasFlag(options::OPT_ffunction_sections,
4597*67e74705SXin Li                    options::OPT_fno_function_sections, UseSeparateSections)) {
4598*67e74705SXin Li     CmdArgs.push_back("-ffunction-sections");
4599*67e74705SXin Li   }
4600*67e74705SXin Li 
4601*67e74705SXin Li   if (Args.hasFlag(options::OPT_fdata_sections, options::OPT_fno_data_sections,
4602*67e74705SXin Li                    UseSeparateSections)) {
4603*67e74705SXin Li     CmdArgs.push_back("-fdata-sections");
4604*67e74705SXin Li   }
4605*67e74705SXin Li 
4606*67e74705SXin Li   if (!Args.hasFlag(options::OPT_funique_section_names,
4607*67e74705SXin Li                     options::OPT_fno_unique_section_names, true))
4608*67e74705SXin Li     CmdArgs.push_back("-fno-unique-section-names");
4609*67e74705SXin Li 
4610*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_finstrument_functions);
4611*67e74705SXin Li 
4612*67e74705SXin Li   if (Args.hasFlag(options::OPT_fxray_instrument,
4613*67e74705SXin Li                    options::OPT_fnoxray_instrument, false)) {
4614*67e74705SXin Li     CmdArgs.push_back("-fxray-instrument");
4615*67e74705SXin Li     if (Arg *A = Args.getLastArg(options::OPT_fxray_instruction_threshold_,
4616*67e74705SXin Li                                  options::OPT_fxray_instruction_threshold_EQ)) {
4617*67e74705SXin Li       CmdArgs.push_back("-fxray-instruction-threshold");
4618*67e74705SXin Li       CmdArgs.push_back(A->getValue());
4619*67e74705SXin Li     }
4620*67e74705SXin Li   }
4621*67e74705SXin Li 
4622*67e74705SXin Li   if (Args.hasFlag(options::OPT_fxray_instrument,
4623*67e74705SXin Li                    options::OPT_fnoxray_instrument, false)) {
4624*67e74705SXin Li     CmdArgs.push_back("-fxray-instrument");
4625*67e74705SXin Li     if (const Arg *A =
4626*67e74705SXin Li             Args.getLastArg(options::OPT_fxray_instruction_threshold_,
4627*67e74705SXin Li                             options::OPT_fxray_instruction_threshold_EQ)) {
4628*67e74705SXin Li       CmdArgs.push_back("-fxray-instruction-threshold");
4629*67e74705SXin Li       CmdArgs.push_back(A->getValue());
4630*67e74705SXin Li     }
4631*67e74705SXin Li   }
4632*67e74705SXin Li 
4633*67e74705SXin Li   addPGOAndCoverageFlags(C, D, Output, Args, CmdArgs);
4634*67e74705SXin Li 
4635*67e74705SXin Li   // Add runtime flag for PS4 when PGO or Coverage are enabled.
4636*67e74705SXin Li   if (getToolChain().getTriple().isPS4CPU())
4637*67e74705SXin Li     addPS4ProfileRTArgs(getToolChain(), Args, CmdArgs);
4638*67e74705SXin Li 
4639*67e74705SXin Li   // Pass options for controlling the default header search paths.
4640*67e74705SXin Li   if (Args.hasArg(options::OPT_nostdinc)) {
4641*67e74705SXin Li     CmdArgs.push_back("-nostdsysteminc");
4642*67e74705SXin Li     CmdArgs.push_back("-nobuiltininc");
4643*67e74705SXin Li   } else {
4644*67e74705SXin Li     if (Args.hasArg(options::OPT_nostdlibinc))
4645*67e74705SXin Li       CmdArgs.push_back("-nostdsysteminc");
4646*67e74705SXin Li     Args.AddLastArg(CmdArgs, options::OPT_nostdincxx);
4647*67e74705SXin Li     Args.AddLastArg(CmdArgs, options::OPT_nobuiltininc);
4648*67e74705SXin Li   }
4649*67e74705SXin Li 
4650*67e74705SXin Li   // Pass the path to compiler resource files.
4651*67e74705SXin Li   CmdArgs.push_back("-resource-dir");
4652*67e74705SXin Li   CmdArgs.push_back(D.ResourceDir.c_str());
4653*67e74705SXin Li 
4654*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_working_directory);
4655*67e74705SXin Li 
4656*67e74705SXin Li   bool ARCMTEnabled = false;
4657*67e74705SXin Li   if (!Args.hasArg(options::OPT_fno_objc_arc, options::OPT_fobjc_arc)) {
4658*67e74705SXin Li     if (const Arg *A = Args.getLastArg(options::OPT_ccc_arcmt_check,
4659*67e74705SXin Li                                        options::OPT_ccc_arcmt_modify,
4660*67e74705SXin Li                                        options::OPT_ccc_arcmt_migrate)) {
4661*67e74705SXin Li       ARCMTEnabled = true;
4662*67e74705SXin Li       switch (A->getOption().getID()) {
4663*67e74705SXin Li       default:
4664*67e74705SXin Li         llvm_unreachable("missed a case");
4665*67e74705SXin Li       case options::OPT_ccc_arcmt_check:
4666*67e74705SXin Li         CmdArgs.push_back("-arcmt-check");
4667*67e74705SXin Li         break;
4668*67e74705SXin Li       case options::OPT_ccc_arcmt_modify:
4669*67e74705SXin Li         CmdArgs.push_back("-arcmt-modify");
4670*67e74705SXin Li         break;
4671*67e74705SXin Li       case options::OPT_ccc_arcmt_migrate:
4672*67e74705SXin Li         CmdArgs.push_back("-arcmt-migrate");
4673*67e74705SXin Li         CmdArgs.push_back("-mt-migrate-directory");
4674*67e74705SXin Li         CmdArgs.push_back(A->getValue());
4675*67e74705SXin Li 
4676*67e74705SXin Li         Args.AddLastArg(CmdArgs, options::OPT_arcmt_migrate_report_output);
4677*67e74705SXin Li         Args.AddLastArg(CmdArgs, options::OPT_arcmt_migrate_emit_arc_errors);
4678*67e74705SXin Li         break;
4679*67e74705SXin Li       }
4680*67e74705SXin Li     }
4681*67e74705SXin Li   } else {
4682*67e74705SXin Li     Args.ClaimAllArgs(options::OPT_ccc_arcmt_check);
4683*67e74705SXin Li     Args.ClaimAllArgs(options::OPT_ccc_arcmt_modify);
4684*67e74705SXin Li     Args.ClaimAllArgs(options::OPT_ccc_arcmt_migrate);
4685*67e74705SXin Li   }
4686*67e74705SXin Li 
4687*67e74705SXin Li   if (const Arg *A = Args.getLastArg(options::OPT_ccc_objcmt_migrate)) {
4688*67e74705SXin Li     if (ARCMTEnabled) {
4689*67e74705SXin Li       D.Diag(diag::err_drv_argument_not_allowed_with) << A->getAsString(Args)
4690*67e74705SXin Li                                                       << "-ccc-arcmt-migrate";
4691*67e74705SXin Li     }
4692*67e74705SXin Li     CmdArgs.push_back("-mt-migrate-directory");
4693*67e74705SXin Li     CmdArgs.push_back(A->getValue());
4694*67e74705SXin Li 
4695*67e74705SXin Li     if (!Args.hasArg(options::OPT_objcmt_migrate_literals,
4696*67e74705SXin Li                      options::OPT_objcmt_migrate_subscripting,
4697*67e74705SXin Li                      options::OPT_objcmt_migrate_property)) {
4698*67e74705SXin Li       // None specified, means enable them all.
4699*67e74705SXin Li       CmdArgs.push_back("-objcmt-migrate-literals");
4700*67e74705SXin Li       CmdArgs.push_back("-objcmt-migrate-subscripting");
4701*67e74705SXin Li       CmdArgs.push_back("-objcmt-migrate-property");
4702*67e74705SXin Li     } else {
4703*67e74705SXin Li       Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_literals);
4704*67e74705SXin Li       Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_subscripting);
4705*67e74705SXin Li       Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_property);
4706*67e74705SXin Li     }
4707*67e74705SXin Li   } else {
4708*67e74705SXin Li     Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_literals);
4709*67e74705SXin Li     Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_subscripting);
4710*67e74705SXin Li     Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_property);
4711*67e74705SXin Li     Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_all);
4712*67e74705SXin Li     Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_readonly_property);
4713*67e74705SXin Li     Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_readwrite_property);
4714*67e74705SXin Li     Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_property_dot_syntax);
4715*67e74705SXin Li     Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_annotation);
4716*67e74705SXin Li     Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_instancetype);
4717*67e74705SXin Li     Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_nsmacros);
4718*67e74705SXin Li     Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_protocol_conformance);
4719*67e74705SXin Li     Args.AddLastArg(CmdArgs, options::OPT_objcmt_atomic_property);
4720*67e74705SXin Li     Args.AddLastArg(CmdArgs, options::OPT_objcmt_returns_innerpointer_property);
4721*67e74705SXin Li     Args.AddLastArg(CmdArgs, options::OPT_objcmt_ns_nonatomic_iosonly);
4722*67e74705SXin Li     Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_designated_init);
4723*67e74705SXin Li     Args.AddLastArg(CmdArgs, options::OPT_objcmt_whitelist_dir_path);
4724*67e74705SXin Li   }
4725*67e74705SXin Li 
4726*67e74705SXin Li   // Add preprocessing options like -I, -D, etc. if we are using the
4727*67e74705SXin Li   // preprocessor.
4728*67e74705SXin Li   //
4729*67e74705SXin Li   // FIXME: Support -fpreprocessed
4730*67e74705SXin Li   if (types::getPreprocessedType(InputType) != types::TY_INVALID)
4731*67e74705SXin Li     AddPreprocessingOptions(C, JA, D, Args, CmdArgs, Output, Inputs,
4732*67e74705SXin Li                             AuxToolChain);
4733*67e74705SXin Li 
4734*67e74705SXin Li   // Don't warn about "clang -c -DPIC -fPIC test.i" because libtool.m4 assumes
4735*67e74705SXin Li   // that "The compiler can only warn and ignore the option if not recognized".
4736*67e74705SXin Li   // When building with ccache, it will pass -D options to clang even on
4737*67e74705SXin Li   // preprocessed inputs and configure concludes that -fPIC is not supported.
4738*67e74705SXin Li   Args.ClaimAllArgs(options::OPT_D);
4739*67e74705SXin Li 
4740*67e74705SXin Li   // Manually translate -O4 to -O3; let clang reject others.
4741*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
4742*67e74705SXin Li     if (A->getOption().matches(options::OPT_O4)) {
4743*67e74705SXin Li       CmdArgs.push_back("-O3");
4744*67e74705SXin Li       D.Diag(diag::warn_O4_is_O3);
4745*67e74705SXin Li     } else {
4746*67e74705SXin Li       A->render(Args, CmdArgs);
4747*67e74705SXin Li     }
4748*67e74705SXin Li   }
4749*67e74705SXin Li 
4750*67e74705SXin Li   // Warn about ignored options to clang.
4751*67e74705SXin Li   for (const Arg *A :
4752*67e74705SXin Li        Args.filtered(options::OPT_clang_ignored_gcc_optimization_f_Group)) {
4753*67e74705SXin Li     D.Diag(diag::warn_ignored_gcc_optimization) << A->getAsString(Args);
4754*67e74705SXin Li     A->claim();
4755*67e74705SXin Li   }
4756*67e74705SXin Li 
4757*67e74705SXin Li   claimNoWarnArgs(Args);
4758*67e74705SXin Li 
4759*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_R_Group);
4760*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_W_Group);
4761*67e74705SXin Li   if (Args.hasFlag(options::OPT_pedantic, options::OPT_no_pedantic, false))
4762*67e74705SXin Li     CmdArgs.push_back("-pedantic");
4763*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_pedantic_errors);
4764*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_w);
4765*67e74705SXin Li 
4766*67e74705SXin Li   // Handle -{std, ansi, trigraphs} -- take the last of -{std, ansi}
4767*67e74705SXin Li   // (-ansi is equivalent to -std=c89 or -std=c++98).
4768*67e74705SXin Li   //
4769*67e74705SXin Li   // If a std is supplied, only add -trigraphs if it follows the
4770*67e74705SXin Li   // option.
4771*67e74705SXin Li   bool ImplyVCPPCXXVer = false;
4772*67e74705SXin Li   if (Arg *Std = Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi)) {
4773*67e74705SXin Li     if (Std->getOption().matches(options::OPT_ansi))
4774*67e74705SXin Li       if (types::isCXX(InputType))
4775*67e74705SXin Li         CmdArgs.push_back("-std=c++98");
4776*67e74705SXin Li       else
4777*67e74705SXin Li         CmdArgs.push_back("-std=c89");
4778*67e74705SXin Li     else
4779*67e74705SXin Li       Std->render(Args, CmdArgs);
4780*67e74705SXin Li 
4781*67e74705SXin Li     // If -f(no-)trigraphs appears after the language standard flag, honor it.
4782*67e74705SXin Li     if (Arg *A = Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi,
4783*67e74705SXin Li                                  options::OPT_ftrigraphs,
4784*67e74705SXin Li                                  options::OPT_fno_trigraphs))
4785*67e74705SXin Li       if (A != Std)
4786*67e74705SXin Li         A->render(Args, CmdArgs);
4787*67e74705SXin Li   } else {
4788*67e74705SXin Li     // Honor -std-default.
4789*67e74705SXin Li     //
4790*67e74705SXin Li     // FIXME: Clang doesn't correctly handle -std= when the input language
4791*67e74705SXin Li     // doesn't match. For the time being just ignore this for C++ inputs;
4792*67e74705SXin Li     // eventually we want to do all the standard defaulting here instead of
4793*67e74705SXin Li     // splitting it between the driver and clang -cc1.
4794*67e74705SXin Li     if (!types::isCXX(InputType))
4795*67e74705SXin Li       Args.AddAllArgsTranslated(CmdArgs, options::OPT_std_default_EQ, "-std=",
4796*67e74705SXin Li                                 /*Joined=*/true);
4797*67e74705SXin Li     else if (IsWindowsMSVC)
4798*67e74705SXin Li       ImplyVCPPCXXVer = true;
4799*67e74705SXin Li 
4800*67e74705SXin Li     Args.AddLastArg(CmdArgs, options::OPT_ftrigraphs,
4801*67e74705SXin Li                     options::OPT_fno_trigraphs);
4802*67e74705SXin Li   }
4803*67e74705SXin Li 
4804*67e74705SXin Li   // GCC's behavior for -Wwrite-strings is a bit strange:
4805*67e74705SXin Li   //  * In C, this "warning flag" changes the types of string literals from
4806*67e74705SXin Li   //    'char[N]' to 'const char[N]', and thus triggers an unrelated warning
4807*67e74705SXin Li   //    for the discarded qualifier.
4808*67e74705SXin Li   //  * In C++, this is just a normal warning flag.
4809*67e74705SXin Li   //
4810*67e74705SXin Li   // Implementing this warning correctly in C is hard, so we follow GCC's
4811*67e74705SXin Li   // behavior for now. FIXME: Directly diagnose uses of a string literal as
4812*67e74705SXin Li   // a non-const char* in C, rather than using this crude hack.
4813*67e74705SXin Li   if (!types::isCXX(InputType)) {
4814*67e74705SXin Li     // FIXME: This should behave just like a warning flag, and thus should also
4815*67e74705SXin Li     // respect -Weverything, -Wno-everything, -Werror=write-strings, and so on.
4816*67e74705SXin Li     Arg *WriteStrings =
4817*67e74705SXin Li         Args.getLastArg(options::OPT_Wwrite_strings,
4818*67e74705SXin Li                         options::OPT_Wno_write_strings, options::OPT_w);
4819*67e74705SXin Li     if (WriteStrings &&
4820*67e74705SXin Li         WriteStrings->getOption().matches(options::OPT_Wwrite_strings))
4821*67e74705SXin Li       CmdArgs.push_back("-fconst-strings");
4822*67e74705SXin Li   }
4823*67e74705SXin Li 
4824*67e74705SXin Li   // GCC provides a macro definition '__DEPRECATED' when -Wdeprecated is active
4825*67e74705SXin Li   // during C++ compilation, which it is by default. GCC keeps this define even
4826*67e74705SXin Li   // in the presence of '-w', match this behavior bug-for-bug.
4827*67e74705SXin Li   if (types::isCXX(InputType) &&
4828*67e74705SXin Li       Args.hasFlag(options::OPT_Wdeprecated, options::OPT_Wno_deprecated,
4829*67e74705SXin Li                    true)) {
4830*67e74705SXin Li     CmdArgs.push_back("-fdeprecated-macro");
4831*67e74705SXin Li   }
4832*67e74705SXin Li 
4833*67e74705SXin Li   // Translate GCC's misnamer '-fasm' arguments to '-fgnu-keywords'.
4834*67e74705SXin Li   if (Arg *Asm = Args.getLastArg(options::OPT_fasm, options::OPT_fno_asm)) {
4835*67e74705SXin Li     if (Asm->getOption().matches(options::OPT_fasm))
4836*67e74705SXin Li       CmdArgs.push_back("-fgnu-keywords");
4837*67e74705SXin Li     else
4838*67e74705SXin Li       CmdArgs.push_back("-fno-gnu-keywords");
4839*67e74705SXin Li   }
4840*67e74705SXin Li 
4841*67e74705SXin Li   if (ShouldDisableDwarfDirectory(Args, getToolChain()))
4842*67e74705SXin Li     CmdArgs.push_back("-fno-dwarf-directory-asm");
4843*67e74705SXin Li 
4844*67e74705SXin Li   if (ShouldDisableAutolink(Args, getToolChain()))
4845*67e74705SXin Li     CmdArgs.push_back("-fno-autolink");
4846*67e74705SXin Li 
4847*67e74705SXin Li   // Add in -fdebug-compilation-dir if necessary.
4848*67e74705SXin Li   addDebugCompDirArg(Args, CmdArgs);
4849*67e74705SXin Li 
4850*67e74705SXin Li   for (const Arg *A : Args.filtered(options::OPT_fdebug_prefix_map_EQ)) {
4851*67e74705SXin Li     StringRef Map = A->getValue();
4852*67e74705SXin Li     if (Map.find('=') == StringRef::npos)
4853*67e74705SXin Li       D.Diag(diag::err_drv_invalid_argument_to_fdebug_prefix_map) << Map;
4854*67e74705SXin Li     else
4855*67e74705SXin Li       CmdArgs.push_back(Args.MakeArgString("-fdebug-prefix-map=" + Map));
4856*67e74705SXin Li     A->claim();
4857*67e74705SXin Li   }
4858*67e74705SXin Li 
4859*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_ftemplate_depth_,
4860*67e74705SXin Li                                options::OPT_ftemplate_depth_EQ)) {
4861*67e74705SXin Li     CmdArgs.push_back("-ftemplate-depth");
4862*67e74705SXin Li     CmdArgs.push_back(A->getValue());
4863*67e74705SXin Li   }
4864*67e74705SXin Li 
4865*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_foperator_arrow_depth_EQ)) {
4866*67e74705SXin Li     CmdArgs.push_back("-foperator-arrow-depth");
4867*67e74705SXin Li     CmdArgs.push_back(A->getValue());
4868*67e74705SXin Li   }
4869*67e74705SXin Li 
4870*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_fconstexpr_depth_EQ)) {
4871*67e74705SXin Li     CmdArgs.push_back("-fconstexpr-depth");
4872*67e74705SXin Li     CmdArgs.push_back(A->getValue());
4873*67e74705SXin Li   }
4874*67e74705SXin Li 
4875*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_fconstexpr_steps_EQ)) {
4876*67e74705SXin Li     CmdArgs.push_back("-fconstexpr-steps");
4877*67e74705SXin Li     CmdArgs.push_back(A->getValue());
4878*67e74705SXin Li   }
4879*67e74705SXin Li 
4880*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_fbracket_depth_EQ)) {
4881*67e74705SXin Li     CmdArgs.push_back("-fbracket-depth");
4882*67e74705SXin Li     CmdArgs.push_back(A->getValue());
4883*67e74705SXin Li   }
4884*67e74705SXin Li 
4885*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_Wlarge_by_value_copy_EQ,
4886*67e74705SXin Li                                options::OPT_Wlarge_by_value_copy_def)) {
4887*67e74705SXin Li     if (A->getNumValues()) {
4888*67e74705SXin Li       StringRef bytes = A->getValue();
4889*67e74705SXin Li       CmdArgs.push_back(Args.MakeArgString("-Wlarge-by-value-copy=" + bytes));
4890*67e74705SXin Li     } else
4891*67e74705SXin Li       CmdArgs.push_back("-Wlarge-by-value-copy=64"); // default value
4892*67e74705SXin Li   }
4893*67e74705SXin Li 
4894*67e74705SXin Li   if (Args.hasArg(options::OPT_relocatable_pch))
4895*67e74705SXin Li     CmdArgs.push_back("-relocatable-pch");
4896*67e74705SXin Li 
4897*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_fconstant_string_class_EQ)) {
4898*67e74705SXin Li     CmdArgs.push_back("-fconstant-string-class");
4899*67e74705SXin Li     CmdArgs.push_back(A->getValue());
4900*67e74705SXin Li   }
4901*67e74705SXin Li 
4902*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_ftabstop_EQ)) {
4903*67e74705SXin Li     CmdArgs.push_back("-ftabstop");
4904*67e74705SXin Li     CmdArgs.push_back(A->getValue());
4905*67e74705SXin Li   }
4906*67e74705SXin Li 
4907*67e74705SXin Li   CmdArgs.push_back("-ferror-limit");
4908*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_ferror_limit_EQ))
4909*67e74705SXin Li     CmdArgs.push_back(A->getValue());
4910*67e74705SXin Li   else
4911*67e74705SXin Li     CmdArgs.push_back("19");
4912*67e74705SXin Li 
4913*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_fmacro_backtrace_limit_EQ)) {
4914*67e74705SXin Li     CmdArgs.push_back("-fmacro-backtrace-limit");
4915*67e74705SXin Li     CmdArgs.push_back(A->getValue());
4916*67e74705SXin Li   }
4917*67e74705SXin Li 
4918*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_ftemplate_backtrace_limit_EQ)) {
4919*67e74705SXin Li     CmdArgs.push_back("-ftemplate-backtrace-limit");
4920*67e74705SXin Li     CmdArgs.push_back(A->getValue());
4921*67e74705SXin Li   }
4922*67e74705SXin Li 
4923*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_fconstexpr_backtrace_limit_EQ)) {
4924*67e74705SXin Li     CmdArgs.push_back("-fconstexpr-backtrace-limit");
4925*67e74705SXin Li     CmdArgs.push_back(A->getValue());
4926*67e74705SXin Li   }
4927*67e74705SXin Li 
4928*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_fspell_checking_limit_EQ)) {
4929*67e74705SXin Li     CmdArgs.push_back("-fspell-checking-limit");
4930*67e74705SXin Li     CmdArgs.push_back(A->getValue());
4931*67e74705SXin Li   }
4932*67e74705SXin Li 
4933*67e74705SXin Li   // Pass -fmessage-length=.
4934*67e74705SXin Li   CmdArgs.push_back("-fmessage-length");
4935*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_fmessage_length_EQ)) {
4936*67e74705SXin Li     CmdArgs.push_back(A->getValue());
4937*67e74705SXin Li   } else {
4938*67e74705SXin Li     // If -fmessage-length=N was not specified, determine whether this is a
4939*67e74705SXin Li     // terminal and, if so, implicitly define -fmessage-length appropriately.
4940*67e74705SXin Li     unsigned N = llvm::sys::Process::StandardErrColumns();
4941*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(Twine(N)));
4942*67e74705SXin Li   }
4943*67e74705SXin Li 
4944*67e74705SXin Li   // -fvisibility= and -fvisibility-ms-compat are of a piece.
4945*67e74705SXin Li   if (const Arg *A = Args.getLastArg(options::OPT_fvisibility_EQ,
4946*67e74705SXin Li                                      options::OPT_fvisibility_ms_compat)) {
4947*67e74705SXin Li     if (A->getOption().matches(options::OPT_fvisibility_EQ)) {
4948*67e74705SXin Li       CmdArgs.push_back("-fvisibility");
4949*67e74705SXin Li       CmdArgs.push_back(A->getValue());
4950*67e74705SXin Li     } else {
4951*67e74705SXin Li       assert(A->getOption().matches(options::OPT_fvisibility_ms_compat));
4952*67e74705SXin Li       CmdArgs.push_back("-fvisibility");
4953*67e74705SXin Li       CmdArgs.push_back("hidden");
4954*67e74705SXin Li       CmdArgs.push_back("-ftype-visibility");
4955*67e74705SXin Li       CmdArgs.push_back("default");
4956*67e74705SXin Li     }
4957*67e74705SXin Li   }
4958*67e74705SXin Li 
4959*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_fvisibility_inlines_hidden);
4960*67e74705SXin Li 
4961*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_ftlsmodel_EQ);
4962*67e74705SXin Li 
4963*67e74705SXin Li   // -fhosted is default.
4964*67e74705SXin Li   if (Args.hasFlag(options::OPT_ffreestanding, options::OPT_fhosted, false) ||
4965*67e74705SXin Li       KernelOrKext)
4966*67e74705SXin Li     CmdArgs.push_back("-ffreestanding");
4967*67e74705SXin Li 
4968*67e74705SXin Li   // Forward -f (flag) options which we can pass directly.
4969*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_femit_all_decls);
4970*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_fheinous_gnu_extensions);
4971*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_fno_operator_names);
4972*67e74705SXin Li   // Emulated TLS is enabled by default on Android, and can be enabled manually
4973*67e74705SXin Li   // with -femulated-tls.
4974*67e74705SXin Li   bool EmulatedTLSDefault = Triple.isAndroid() || Triple.isWindowsCygwinEnvironment();
4975*67e74705SXin Li   if (Args.hasFlag(options::OPT_femulated_tls, options::OPT_fno_emulated_tls,
4976*67e74705SXin Li                    EmulatedTLSDefault))
4977*67e74705SXin Li     CmdArgs.push_back("-femulated-tls");
4978*67e74705SXin Li   // AltiVec-like language extensions aren't relevant for assembling.
4979*67e74705SXin Li   if (!isa<PreprocessJobAction>(JA) || Output.getType() != types::TY_PP_Asm) {
4980*67e74705SXin Li     Args.AddLastArg(CmdArgs, options::OPT_faltivec);
4981*67e74705SXin Li     Args.AddLastArg(CmdArgs, options::OPT_fzvector);
4982*67e74705SXin Li   }
4983*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_show_template_tree);
4984*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_fno_elide_type);
4985*67e74705SXin Li 
4986*67e74705SXin Li   // Forward flags for OpenMP
4987*67e74705SXin Li   if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
4988*67e74705SXin Li                    options::OPT_fno_openmp, false)) {
4989*67e74705SXin Li     switch (getOpenMPRuntime(getToolChain(), Args)) {
4990*67e74705SXin Li     case OMPRT_OMP:
4991*67e74705SXin Li     case OMPRT_IOMP5:
4992*67e74705SXin Li       // Clang can generate useful OpenMP code for these two runtime libraries.
4993*67e74705SXin Li       CmdArgs.push_back("-fopenmp");
4994*67e74705SXin Li 
4995*67e74705SXin Li       // If no option regarding the use of TLS in OpenMP codegeneration is
4996*67e74705SXin Li       // given, decide a default based on the target. Otherwise rely on the
4997*67e74705SXin Li       // options and pass the right information to the frontend.
4998*67e74705SXin Li       if (!Args.hasFlag(options::OPT_fopenmp_use_tls,
4999*67e74705SXin Li                         options::OPT_fnoopenmp_use_tls, /*Default=*/true))
5000*67e74705SXin Li         CmdArgs.push_back("-fnoopenmp-use-tls");
5001*67e74705SXin Li       Args.AddAllArgs(CmdArgs, options::OPT_fopenmp_version_EQ);
5002*67e74705SXin Li       break;
5003*67e74705SXin Li     default:
5004*67e74705SXin Li       // By default, if Clang doesn't know how to generate useful OpenMP code
5005*67e74705SXin Li       // for a specific runtime library, we just don't pass the '-fopenmp' flag
5006*67e74705SXin Li       // down to the actual compilation.
5007*67e74705SXin Li       // FIXME: It would be better to have a mode which *only* omits IR
5008*67e74705SXin Li       // generation based on the OpenMP support so that we get consistent
5009*67e74705SXin Li       // semantic analysis, etc.
5010*67e74705SXin Li       break;
5011*67e74705SXin Li     }
5012*67e74705SXin Li   }
5013*67e74705SXin Li 
5014*67e74705SXin Li   const SanitizerArgs &Sanitize = getToolChain().getSanitizerArgs();
5015*67e74705SXin Li   Sanitize.addArgs(getToolChain(), Args, CmdArgs, InputType);
5016*67e74705SXin Li 
5017*67e74705SXin Li   // Report an error for -faltivec on anything other than PowerPC.
5018*67e74705SXin Li   if (const Arg *A = Args.getLastArg(options::OPT_faltivec)) {
5019*67e74705SXin Li     const llvm::Triple::ArchType Arch = getToolChain().getArch();
5020*67e74705SXin Li     if (!(Arch == llvm::Triple::ppc || Arch == llvm::Triple::ppc64 ||
5021*67e74705SXin Li           Arch == llvm::Triple::ppc64le))
5022*67e74705SXin Li       D.Diag(diag::err_drv_argument_only_allowed_with) << A->getAsString(Args)
5023*67e74705SXin Li                                                        << "ppc/ppc64/ppc64le";
5024*67e74705SXin Li   }
5025*67e74705SXin Li 
5026*67e74705SXin Li   // -fzvector is incompatible with -faltivec.
5027*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_fzvector))
5028*67e74705SXin Li     if (Args.hasArg(options::OPT_faltivec))
5029*67e74705SXin Li       D.Diag(diag::err_drv_argument_not_allowed_with) << A->getAsString(Args)
5030*67e74705SXin Li                                                       << "-faltivec";
5031*67e74705SXin Li 
5032*67e74705SXin Li   if (getToolChain().SupportsProfiling())
5033*67e74705SXin Li     Args.AddLastArg(CmdArgs, options::OPT_pg);
5034*67e74705SXin Li 
5035*67e74705SXin Li   // -flax-vector-conversions is default.
5036*67e74705SXin Li   if (!Args.hasFlag(options::OPT_flax_vector_conversions,
5037*67e74705SXin Li                     options::OPT_fno_lax_vector_conversions))
5038*67e74705SXin Li     CmdArgs.push_back("-fno-lax-vector-conversions");
5039*67e74705SXin Li 
5040*67e74705SXin Li   if (Args.getLastArg(options::OPT_fapple_kext) ||
5041*67e74705SXin Li       (Args.hasArg(options::OPT_mkernel) && types::isCXX(InputType)))
5042*67e74705SXin Li     CmdArgs.push_back("-fapple-kext");
5043*67e74705SXin Li 
5044*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_fobjc_sender_dependent_dispatch);
5045*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_print_source_range_info);
5046*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_parseable_fixits);
5047*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_ftime_report);
5048*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_ftrapv);
5049*67e74705SXin Li 
5050*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_ftrapv_handler_EQ)) {
5051*67e74705SXin Li     CmdArgs.push_back("-ftrapv-handler");
5052*67e74705SXin Li     CmdArgs.push_back(A->getValue());
5053*67e74705SXin Li   }
5054*67e74705SXin Li 
5055*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_ftrap_function_EQ);
5056*67e74705SXin Li 
5057*67e74705SXin Li   // -fno-strict-overflow implies -fwrapv if it isn't disabled, but
5058*67e74705SXin Li   // -fstrict-overflow won't turn off an explicitly enabled -fwrapv.
5059*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_fwrapv, options::OPT_fno_wrapv)) {
5060*67e74705SXin Li     if (A->getOption().matches(options::OPT_fwrapv))
5061*67e74705SXin Li       CmdArgs.push_back("-fwrapv");
5062*67e74705SXin Li   } else if (Arg *A = Args.getLastArg(options::OPT_fstrict_overflow,
5063*67e74705SXin Li                                       options::OPT_fno_strict_overflow)) {
5064*67e74705SXin Li     if (A->getOption().matches(options::OPT_fno_strict_overflow))
5065*67e74705SXin Li       CmdArgs.push_back("-fwrapv");
5066*67e74705SXin Li   }
5067*67e74705SXin Li 
5068*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_freroll_loops,
5069*67e74705SXin Li                                options::OPT_fno_reroll_loops))
5070*67e74705SXin Li     if (A->getOption().matches(options::OPT_freroll_loops))
5071*67e74705SXin Li       CmdArgs.push_back("-freroll-loops");
5072*67e74705SXin Li 
5073*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_fwritable_strings);
5074*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_funroll_loops,
5075*67e74705SXin Li                   options::OPT_fno_unroll_loops);
5076*67e74705SXin Li 
5077*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_pthread);
5078*67e74705SXin Li 
5079*67e74705SXin Li   // -stack-protector=0 is default.
5080*67e74705SXin Li   unsigned StackProtectorLevel = 0;
5081*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_fno_stack_protector,
5082*67e74705SXin Li                                options::OPT_fstack_protector_all,
5083*67e74705SXin Li                                options::OPT_fstack_protector_strong,
5084*67e74705SXin Li                                options::OPT_fstack_protector)) {
5085*67e74705SXin Li     if (A->getOption().matches(options::OPT_fstack_protector)) {
5086*67e74705SXin Li       StackProtectorLevel = std::max<unsigned>(
5087*67e74705SXin Li           LangOptions::SSPOn,
5088*67e74705SXin Li           getToolChain().GetDefaultStackProtectorLevel(KernelOrKext));
5089*67e74705SXin Li     } else if (A->getOption().matches(options::OPT_fstack_protector_strong))
5090*67e74705SXin Li       StackProtectorLevel = LangOptions::SSPStrong;
5091*67e74705SXin Li     else if (A->getOption().matches(options::OPT_fstack_protector_all))
5092*67e74705SXin Li       StackProtectorLevel = LangOptions::SSPReq;
5093*67e74705SXin Li   } else {
5094*67e74705SXin Li     StackProtectorLevel =
5095*67e74705SXin Li         getToolChain().GetDefaultStackProtectorLevel(KernelOrKext);
5096*67e74705SXin Li   }
5097*67e74705SXin Li   if (StackProtectorLevel) {
5098*67e74705SXin Li     CmdArgs.push_back("-stack-protector");
5099*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(Twine(StackProtectorLevel)));
5100*67e74705SXin Li   }
5101*67e74705SXin Li 
5102*67e74705SXin Li   // --param ssp-buffer-size=
5103*67e74705SXin Li   for (const Arg *A : Args.filtered(options::OPT__param)) {
5104*67e74705SXin Li     StringRef Str(A->getValue());
5105*67e74705SXin Li     if (Str.startswith("ssp-buffer-size=")) {
5106*67e74705SXin Li       if (StackProtectorLevel) {
5107*67e74705SXin Li         CmdArgs.push_back("-stack-protector-buffer-size");
5108*67e74705SXin Li         // FIXME: Verify the argument is a valid integer.
5109*67e74705SXin Li         CmdArgs.push_back(Args.MakeArgString(Str.drop_front(16)));
5110*67e74705SXin Li       }
5111*67e74705SXin Li       A->claim();
5112*67e74705SXin Li     }
5113*67e74705SXin Li   }
5114*67e74705SXin Li 
5115*67e74705SXin Li   // Translate -mstackrealign
5116*67e74705SXin Li   if (Args.hasFlag(options::OPT_mstackrealign, options::OPT_mno_stackrealign,
5117*67e74705SXin Li                    false))
5118*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString("-mstackrealign"));
5119*67e74705SXin Li 
5120*67e74705SXin Li   if (Args.hasArg(options::OPT_mstack_alignment)) {
5121*67e74705SXin Li     StringRef alignment = Args.getLastArgValue(options::OPT_mstack_alignment);
5122*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString("-mstack-alignment=" + alignment));
5123*67e74705SXin Li   }
5124*67e74705SXin Li 
5125*67e74705SXin Li   if (Args.hasArg(options::OPT_mstack_probe_size)) {
5126*67e74705SXin Li     StringRef Size = Args.getLastArgValue(options::OPT_mstack_probe_size);
5127*67e74705SXin Li 
5128*67e74705SXin Li     if (!Size.empty())
5129*67e74705SXin Li       CmdArgs.push_back(Args.MakeArgString("-mstack-probe-size=" + Size));
5130*67e74705SXin Li     else
5131*67e74705SXin Li       CmdArgs.push_back("-mstack-probe-size=0");
5132*67e74705SXin Li   }
5133*67e74705SXin Li 
5134*67e74705SXin Li   switch (getToolChain().getArch()) {
5135*67e74705SXin Li   case llvm::Triple::aarch64:
5136*67e74705SXin Li   case llvm::Triple::aarch64_be:
5137*67e74705SXin Li   case llvm::Triple::arm:
5138*67e74705SXin Li   case llvm::Triple::armeb:
5139*67e74705SXin Li   case llvm::Triple::thumb:
5140*67e74705SXin Li   case llvm::Triple::thumbeb:
5141*67e74705SXin Li     CmdArgs.push_back("-fallow-half-arguments-and-returns");
5142*67e74705SXin Li     break;
5143*67e74705SXin Li 
5144*67e74705SXin Li   default:
5145*67e74705SXin Li     break;
5146*67e74705SXin Li   }
5147*67e74705SXin Li 
5148*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_mrestrict_it,
5149*67e74705SXin Li                                options::OPT_mno_restrict_it)) {
5150*67e74705SXin Li     if (A->getOption().matches(options::OPT_mrestrict_it)) {
5151*67e74705SXin Li       CmdArgs.push_back("-backend-option");
5152*67e74705SXin Li       CmdArgs.push_back("-arm-restrict-it");
5153*67e74705SXin Li     } else {
5154*67e74705SXin Li       CmdArgs.push_back("-backend-option");
5155*67e74705SXin Li       CmdArgs.push_back("-arm-no-restrict-it");
5156*67e74705SXin Li     }
5157*67e74705SXin Li   } else if (Triple.isOSWindows() &&
5158*67e74705SXin Li              (Triple.getArch() == llvm::Triple::arm ||
5159*67e74705SXin Li               Triple.getArch() == llvm::Triple::thumb)) {
5160*67e74705SXin Li     // Windows on ARM expects restricted IT blocks
5161*67e74705SXin Li     CmdArgs.push_back("-backend-option");
5162*67e74705SXin Li     CmdArgs.push_back("-arm-restrict-it");
5163*67e74705SXin Li   }
5164*67e74705SXin Li 
5165*67e74705SXin Li   // Forward -cl options to -cc1
5166*67e74705SXin Li   if (Args.getLastArg(options::OPT_cl_opt_disable)) {
5167*67e74705SXin Li     CmdArgs.push_back("-cl-opt-disable");
5168*67e74705SXin Li   }
5169*67e74705SXin Li   if (Args.getLastArg(options::OPT_cl_strict_aliasing)) {
5170*67e74705SXin Li     CmdArgs.push_back("-cl-strict-aliasing");
5171*67e74705SXin Li   }
5172*67e74705SXin Li   if (Args.getLastArg(options::OPT_cl_single_precision_constant)) {
5173*67e74705SXin Li     CmdArgs.push_back("-cl-single-precision-constant");
5174*67e74705SXin Li   }
5175*67e74705SXin Li   if (Args.getLastArg(options::OPT_cl_finite_math_only)) {
5176*67e74705SXin Li     CmdArgs.push_back("-cl-finite-math-only");
5177*67e74705SXin Li   }
5178*67e74705SXin Li   if (Args.getLastArg(options::OPT_cl_kernel_arg_info)) {
5179*67e74705SXin Li     CmdArgs.push_back("-cl-kernel-arg-info");
5180*67e74705SXin Li   }
5181*67e74705SXin Li   if (Args.getLastArg(options::OPT_cl_unsafe_math_optimizations)) {
5182*67e74705SXin Li     CmdArgs.push_back("-cl-unsafe-math-optimizations");
5183*67e74705SXin Li   }
5184*67e74705SXin Li   if (Args.getLastArg(options::OPT_cl_fast_relaxed_math)) {
5185*67e74705SXin Li     CmdArgs.push_back("-cl-fast-relaxed-math");
5186*67e74705SXin Li   }
5187*67e74705SXin Li   if (Args.getLastArg(options::OPT_cl_mad_enable)) {
5188*67e74705SXin Li     CmdArgs.push_back("-cl-mad-enable");
5189*67e74705SXin Li   }
5190*67e74705SXin Li   if (Args.getLastArg(options::OPT_cl_no_signed_zeros)) {
5191*67e74705SXin Li     CmdArgs.push_back("-cl-no-signed-zeros");
5192*67e74705SXin Li   }
5193*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_cl_std_EQ)) {
5194*67e74705SXin Li     std::string CLStdStr = "-cl-std=";
5195*67e74705SXin Li     CLStdStr += A->getValue();
5196*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(CLStdStr));
5197*67e74705SXin Li   }
5198*67e74705SXin Li   if (Args.getLastArg(options::OPT_cl_denorms_are_zero)) {
5199*67e74705SXin Li     CmdArgs.push_back("-cl-denorms-are-zero");
5200*67e74705SXin Li   }
5201*67e74705SXin Li 
5202*67e74705SXin Li   // Forward -f options with positive and negative forms; we translate
5203*67e74705SXin Li   // these by hand.
5204*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_fprofile_sample_use_EQ)) {
5205*67e74705SXin Li     StringRef fname = A->getValue();
5206*67e74705SXin Li     if (!llvm::sys::fs::exists(fname))
5207*67e74705SXin Li       D.Diag(diag::err_drv_no_such_file) << fname;
5208*67e74705SXin Li     else
5209*67e74705SXin Li       A->render(Args, CmdArgs);
5210*67e74705SXin Li   }
5211*67e74705SXin Li 
5212*67e74705SXin Li   // -fbuiltin is default unless -mkernel is used.
5213*67e74705SXin Li   bool UseBuiltins =
5214*67e74705SXin Li       Args.hasFlag(options::OPT_fbuiltin, options::OPT_fno_builtin,
5215*67e74705SXin Li                    !Args.hasArg(options::OPT_mkernel));
5216*67e74705SXin Li   if (!UseBuiltins)
5217*67e74705SXin Li     CmdArgs.push_back("-fno-builtin");
5218*67e74705SXin Li 
5219*67e74705SXin Li   // -ffreestanding implies -fno-builtin.
5220*67e74705SXin Li   if (Args.hasArg(options::OPT_ffreestanding))
5221*67e74705SXin Li     UseBuiltins = false;
5222*67e74705SXin Li 
5223*67e74705SXin Li   // Process the -fno-builtin-* options.
5224*67e74705SXin Li   for (const auto &Arg : Args) {
5225*67e74705SXin Li     const Option &O = Arg->getOption();
5226*67e74705SXin Li     if (!O.matches(options::OPT_fno_builtin_))
5227*67e74705SXin Li       continue;
5228*67e74705SXin Li 
5229*67e74705SXin Li     Arg->claim();
5230*67e74705SXin Li     // If -fno-builtin is specified, then there's no need to pass the option to
5231*67e74705SXin Li     // the frontend.
5232*67e74705SXin Li     if (!UseBuiltins)
5233*67e74705SXin Li       continue;
5234*67e74705SXin Li 
5235*67e74705SXin Li     StringRef FuncName = Arg->getValue();
5236*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString("-fno-builtin-" + FuncName));
5237*67e74705SXin Li   }
5238*67e74705SXin Li 
5239*67e74705SXin Li   if (!Args.hasFlag(options::OPT_fassume_sane_operator_new,
5240*67e74705SXin Li                     options::OPT_fno_assume_sane_operator_new))
5241*67e74705SXin Li     CmdArgs.push_back("-fno-assume-sane-operator-new");
5242*67e74705SXin Li 
5243*67e74705SXin Li   // -fblocks=0 is default.
5244*67e74705SXin Li   if (Args.hasFlag(options::OPT_fblocks, options::OPT_fno_blocks,
5245*67e74705SXin Li                    getToolChain().IsBlocksDefault()) ||
5246*67e74705SXin Li       (Args.hasArg(options::OPT_fgnu_runtime) &&
5247*67e74705SXin Li        Args.hasArg(options::OPT_fobjc_nonfragile_abi) &&
5248*67e74705SXin Li        !Args.hasArg(options::OPT_fno_blocks))) {
5249*67e74705SXin Li     CmdArgs.push_back("-fblocks");
5250*67e74705SXin Li 
5251*67e74705SXin Li     if (!Args.hasArg(options::OPT_fgnu_runtime) &&
5252*67e74705SXin Li         !getToolChain().hasBlocksRuntime())
5253*67e74705SXin Li       CmdArgs.push_back("-fblocks-runtime-optional");
5254*67e74705SXin Li   }
5255*67e74705SXin Li 
5256*67e74705SXin Li   // -fmodules enables the use of precompiled modules (off by default).
5257*67e74705SXin Li   // Users can pass -fno-cxx-modules to turn off modules support for
5258*67e74705SXin Li   // C++/Objective-C++ programs.
5259*67e74705SXin Li   bool HaveModules = false;
5260*67e74705SXin Li   if (Args.hasFlag(options::OPT_fmodules, options::OPT_fno_modules, false)) {
5261*67e74705SXin Li     bool AllowedInCXX = Args.hasFlag(options::OPT_fcxx_modules,
5262*67e74705SXin Li                                      options::OPT_fno_cxx_modules, true);
5263*67e74705SXin Li     if (AllowedInCXX || !types::isCXX(InputType)) {
5264*67e74705SXin Li       CmdArgs.push_back("-fmodules");
5265*67e74705SXin Li       HaveModules = true;
5266*67e74705SXin Li     }
5267*67e74705SXin Li   }
5268*67e74705SXin Li 
5269*67e74705SXin Li   // -fmodule-maps enables implicit reading of module map files. By default,
5270*67e74705SXin Li   // this is enabled if we are using precompiled modules.
5271*67e74705SXin Li   if (Args.hasFlag(options::OPT_fimplicit_module_maps,
5272*67e74705SXin Li                    options::OPT_fno_implicit_module_maps, HaveModules)) {
5273*67e74705SXin Li     CmdArgs.push_back("-fimplicit-module-maps");
5274*67e74705SXin Li   }
5275*67e74705SXin Li 
5276*67e74705SXin Li   // -fmodules-decluse checks that modules used are declared so (off by
5277*67e74705SXin Li   // default).
5278*67e74705SXin Li   if (Args.hasFlag(options::OPT_fmodules_decluse,
5279*67e74705SXin Li                    options::OPT_fno_modules_decluse, false)) {
5280*67e74705SXin Li     CmdArgs.push_back("-fmodules-decluse");
5281*67e74705SXin Li   }
5282*67e74705SXin Li 
5283*67e74705SXin Li   // -fmodules-strict-decluse is like -fmodule-decluse, but also checks that
5284*67e74705SXin Li   // all #included headers are part of modules.
5285*67e74705SXin Li   if (Args.hasFlag(options::OPT_fmodules_strict_decluse,
5286*67e74705SXin Li                    options::OPT_fno_modules_strict_decluse, false)) {
5287*67e74705SXin Li     CmdArgs.push_back("-fmodules-strict-decluse");
5288*67e74705SXin Li   }
5289*67e74705SXin Li 
5290*67e74705SXin Li   // -fno-implicit-modules turns off implicitly compiling modules on demand.
5291*67e74705SXin Li   if (!Args.hasFlag(options::OPT_fimplicit_modules,
5292*67e74705SXin Li                     options::OPT_fno_implicit_modules)) {
5293*67e74705SXin Li     CmdArgs.push_back("-fno-implicit-modules");
5294*67e74705SXin Li   } else if (HaveModules) {
5295*67e74705SXin Li     // -fmodule-cache-path specifies where our implicitly-built module files
5296*67e74705SXin Li     // should be written.
5297*67e74705SXin Li     SmallString<128> Path;
5298*67e74705SXin Li     if (Arg *A = Args.getLastArg(options::OPT_fmodules_cache_path))
5299*67e74705SXin Li       Path = A->getValue();
5300*67e74705SXin Li     if (C.isForDiagnostics()) {
5301*67e74705SXin Li       // When generating crash reports, we want to emit the modules along with
5302*67e74705SXin Li       // the reproduction sources, so we ignore any provided module path.
5303*67e74705SXin Li       Path = Output.getFilename();
5304*67e74705SXin Li       llvm::sys::path::replace_extension(Path, ".cache");
5305*67e74705SXin Li       llvm::sys::path::append(Path, "modules");
5306*67e74705SXin Li     } else if (Path.empty()) {
5307*67e74705SXin Li       // No module path was provided: use the default.
5308*67e74705SXin Li       llvm::sys::path::system_temp_directory(/*erasedOnReboot=*/false, Path);
5309*67e74705SXin Li       llvm::sys::path::append(Path, "org.llvm.clang.");
5310*67e74705SXin Li       appendUserToPath(Path);
5311*67e74705SXin Li       llvm::sys::path::append(Path, "ModuleCache");
5312*67e74705SXin Li     }
5313*67e74705SXin Li     const char Arg[] = "-fmodules-cache-path=";
5314*67e74705SXin Li     Path.insert(Path.begin(), Arg, Arg + strlen(Arg));
5315*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(Path));
5316*67e74705SXin Li   }
5317*67e74705SXin Li 
5318*67e74705SXin Li   // -fmodule-name specifies the module that is currently being built (or
5319*67e74705SXin Li   // used for header checking by -fmodule-maps).
5320*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_fmodule_name_EQ);
5321*67e74705SXin Li 
5322*67e74705SXin Li   // -fmodule-map-file can be used to specify files containing module
5323*67e74705SXin Li   // definitions.
5324*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_fmodule_map_file);
5325*67e74705SXin Li 
5326*67e74705SXin Li   // -fmodule-file can be used to specify files containing precompiled modules.
5327*67e74705SXin Li   if (HaveModules)
5328*67e74705SXin Li     Args.AddAllArgs(CmdArgs, options::OPT_fmodule_file);
5329*67e74705SXin Li   else
5330*67e74705SXin Li     Args.ClaimAllArgs(options::OPT_fmodule_file);
5331*67e74705SXin Li 
5332*67e74705SXin Li   // When building modules and generating crashdumps, we need to dump a module
5333*67e74705SXin Li   // dependency VFS alongside the output.
5334*67e74705SXin Li   if (HaveModules && C.isForDiagnostics()) {
5335*67e74705SXin Li     SmallString<128> VFSDir(Output.getFilename());
5336*67e74705SXin Li     llvm::sys::path::replace_extension(VFSDir, ".cache");
5337*67e74705SXin Li     // Add the cache directory as a temp so the crash diagnostics pick it up.
5338*67e74705SXin Li     C.addTempFile(Args.MakeArgString(VFSDir));
5339*67e74705SXin Li 
5340*67e74705SXin Li     llvm::sys::path::append(VFSDir, "vfs");
5341*67e74705SXin Li     CmdArgs.push_back("-module-dependency-dir");
5342*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(VFSDir));
5343*67e74705SXin Li   }
5344*67e74705SXin Li 
5345*67e74705SXin Li   if (HaveModules)
5346*67e74705SXin Li     Args.AddLastArg(CmdArgs, options::OPT_fmodules_user_build_path);
5347*67e74705SXin Li 
5348*67e74705SXin Li   // Pass through all -fmodules-ignore-macro arguments.
5349*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_fmodules_ignore_macro);
5350*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_fmodules_prune_interval);
5351*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_fmodules_prune_after);
5352*67e74705SXin Li 
5353*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_fbuild_session_timestamp);
5354*67e74705SXin Li 
5355*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_fbuild_session_file)) {
5356*67e74705SXin Li     if (Args.hasArg(options::OPT_fbuild_session_timestamp))
5357*67e74705SXin Li       D.Diag(diag::err_drv_argument_not_allowed_with)
5358*67e74705SXin Li           << A->getAsString(Args) << "-fbuild-session-timestamp";
5359*67e74705SXin Li 
5360*67e74705SXin Li     llvm::sys::fs::file_status Status;
5361*67e74705SXin Li     if (llvm::sys::fs::status(A->getValue(), Status))
5362*67e74705SXin Li       D.Diag(diag::err_drv_no_such_file) << A->getValue();
5363*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(
5364*67e74705SXin Li         "-fbuild-session-timestamp=" +
5365*67e74705SXin Li         Twine((uint64_t)Status.getLastModificationTime().toEpochTime())));
5366*67e74705SXin Li   }
5367*67e74705SXin Li 
5368*67e74705SXin Li   if (Args.getLastArg(options::OPT_fmodules_validate_once_per_build_session)) {
5369*67e74705SXin Li     if (!Args.getLastArg(options::OPT_fbuild_session_timestamp,
5370*67e74705SXin Li                          options::OPT_fbuild_session_file))
5371*67e74705SXin Li       D.Diag(diag::err_drv_modules_validate_once_requires_timestamp);
5372*67e74705SXin Li 
5373*67e74705SXin Li     Args.AddLastArg(CmdArgs,
5374*67e74705SXin Li                     options::OPT_fmodules_validate_once_per_build_session);
5375*67e74705SXin Li   }
5376*67e74705SXin Li 
5377*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_fmodules_validate_system_headers);
5378*67e74705SXin Li 
5379*67e74705SXin Li   // -faccess-control is default.
5380*67e74705SXin Li   if (Args.hasFlag(options::OPT_fno_access_control,
5381*67e74705SXin Li                    options::OPT_faccess_control, false))
5382*67e74705SXin Li     CmdArgs.push_back("-fno-access-control");
5383*67e74705SXin Li 
5384*67e74705SXin Li   // -felide-constructors is the default.
5385*67e74705SXin Li   if (Args.hasFlag(options::OPT_fno_elide_constructors,
5386*67e74705SXin Li                    options::OPT_felide_constructors, false))
5387*67e74705SXin Li     CmdArgs.push_back("-fno-elide-constructors");
5388*67e74705SXin Li 
5389*67e74705SXin Li   ToolChain::RTTIMode RTTIMode = getToolChain().getRTTIMode();
5390*67e74705SXin Li 
5391*67e74705SXin Li   if (KernelOrKext || (types::isCXX(InputType) &&
5392*67e74705SXin Li                        (RTTIMode == ToolChain::RM_DisabledExplicitly ||
5393*67e74705SXin Li                         RTTIMode == ToolChain::RM_DisabledImplicitly)))
5394*67e74705SXin Li     CmdArgs.push_back("-fno-rtti");
5395*67e74705SXin Li 
5396*67e74705SXin Li   // -fshort-enums=0 is default for all architectures except Hexagon.
5397*67e74705SXin Li   if (Args.hasFlag(options::OPT_fshort_enums, options::OPT_fno_short_enums,
5398*67e74705SXin Li                    getToolChain().getArch() == llvm::Triple::hexagon))
5399*67e74705SXin Li     CmdArgs.push_back("-fshort-enums");
5400*67e74705SXin Li 
5401*67e74705SXin Li   // -fsigned-char is default.
5402*67e74705SXin Li   if (Arg *A = Args.getLastArg(
5403*67e74705SXin Li           options::OPT_fsigned_char, options::OPT_fno_signed_char,
5404*67e74705SXin Li           options::OPT_funsigned_char, options::OPT_fno_unsigned_char)) {
5405*67e74705SXin Li     if (A->getOption().matches(options::OPT_funsigned_char) ||
5406*67e74705SXin Li         A->getOption().matches(options::OPT_fno_signed_char)) {
5407*67e74705SXin Li       CmdArgs.push_back("-fno-signed-char");
5408*67e74705SXin Li     }
5409*67e74705SXin Li   } else if (!isSignedCharDefault(getToolChain().getTriple())) {
5410*67e74705SXin Li     CmdArgs.push_back("-fno-signed-char");
5411*67e74705SXin Li   }
5412*67e74705SXin Li 
5413*67e74705SXin Li   // -fuse-cxa-atexit is default.
5414*67e74705SXin Li   if (!Args.hasFlag(
5415*67e74705SXin Li           options::OPT_fuse_cxa_atexit, options::OPT_fno_use_cxa_atexit,
5416*67e74705SXin Li           !IsWindowsCygnus && !IsWindowsGNU &&
5417*67e74705SXin Li               getToolChain().getTriple().getOS() != llvm::Triple::Solaris &&
5418*67e74705SXin Li               getToolChain().getArch() != llvm::Triple::hexagon &&
5419*67e74705SXin Li               getToolChain().getArch() != llvm::Triple::xcore &&
5420*67e74705SXin Li               ((getToolChain().getTriple().getVendor() !=
5421*67e74705SXin Li                 llvm::Triple::MipsTechnologies) ||
5422*67e74705SXin Li                getToolChain().getTriple().hasEnvironment())) ||
5423*67e74705SXin Li       KernelOrKext)
5424*67e74705SXin Li     CmdArgs.push_back("-fno-use-cxa-atexit");
5425*67e74705SXin Li 
5426*67e74705SXin Li   // -fms-extensions=0 is default.
5427*67e74705SXin Li   if (Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions,
5428*67e74705SXin Li                    IsWindowsMSVC))
5429*67e74705SXin Li     CmdArgs.push_back("-fms-extensions");
5430*67e74705SXin Li 
5431*67e74705SXin Li   // -fno-use-line-directives is default.
5432*67e74705SXin Li   if (Args.hasFlag(options::OPT_fuse_line_directives,
5433*67e74705SXin Li                    options::OPT_fno_use_line_directives, false))
5434*67e74705SXin Li     CmdArgs.push_back("-fuse-line-directives");
5435*67e74705SXin Li 
5436*67e74705SXin Li   // -fms-compatibility=0 is default.
5437*67e74705SXin Li   if (Args.hasFlag(options::OPT_fms_compatibility,
5438*67e74705SXin Li                    options::OPT_fno_ms_compatibility,
5439*67e74705SXin Li                    (IsWindowsMSVC &&
5440*67e74705SXin Li                     Args.hasFlag(options::OPT_fms_extensions,
5441*67e74705SXin Li                                  options::OPT_fno_ms_extensions, true))))
5442*67e74705SXin Li     CmdArgs.push_back("-fms-compatibility");
5443*67e74705SXin Li 
5444*67e74705SXin Li   // -fms-compatibility-version=18.00 is default.
5445*67e74705SXin Li   VersionTuple MSVT = visualstudio::getMSVCVersion(
5446*67e74705SXin Li       &D, getToolChain(), getToolChain().getTriple(), Args, IsWindowsMSVC);
5447*67e74705SXin Li   if (!MSVT.empty())
5448*67e74705SXin Li     CmdArgs.push_back(
5449*67e74705SXin Li         Args.MakeArgString("-fms-compatibility-version=" + MSVT.getAsString()));
5450*67e74705SXin Li 
5451*67e74705SXin Li   bool IsMSVC2015Compatible = MSVT.getMajor() >= 19;
5452*67e74705SXin Li   if (ImplyVCPPCXXVer) {
5453*67e74705SXin Li     StringRef LanguageStandard;
5454*67e74705SXin Li     if (const Arg *StdArg = Args.getLastArg(options::OPT__SLASH_std)) {
5455*67e74705SXin Li       LanguageStandard = llvm::StringSwitch<StringRef>(StdArg->getValue())
5456*67e74705SXin Li                              .Case("c++14", "-std=c++14")
5457*67e74705SXin Li                              .Case("c++latest", "-std=c++1z")
5458*67e74705SXin Li                              .Default("");
5459*67e74705SXin Li       if (LanguageStandard.empty())
5460*67e74705SXin Li         D.Diag(clang::diag::warn_drv_unused_argument)
5461*67e74705SXin Li             << StdArg->getAsString(Args);
5462*67e74705SXin Li     }
5463*67e74705SXin Li 
5464*67e74705SXin Li     if (LanguageStandard.empty()) {
5465*67e74705SXin Li       if (IsMSVC2015Compatible)
5466*67e74705SXin Li         LanguageStandard = "-std=c++14";
5467*67e74705SXin Li       else
5468*67e74705SXin Li         LanguageStandard = "-std=c++11";
5469*67e74705SXin Li     }
5470*67e74705SXin Li 
5471*67e74705SXin Li     CmdArgs.push_back(LanguageStandard.data());
5472*67e74705SXin Li   }
5473*67e74705SXin Li 
5474*67e74705SXin Li   // -fno-borland-extensions is default.
5475*67e74705SXin Li   if (Args.hasFlag(options::OPT_fborland_extensions,
5476*67e74705SXin Li                    options::OPT_fno_borland_extensions, false))
5477*67e74705SXin Li     CmdArgs.push_back("-fborland-extensions");
5478*67e74705SXin Li 
5479*67e74705SXin Li   // -fno-declspec is default, except for PS4.
5480*67e74705SXin Li   if (Args.hasFlag(options::OPT_fdeclspec, options::OPT_fno_declspec,
5481*67e74705SXin Li                    getToolChain().getTriple().isPS4()))
5482*67e74705SXin Li     CmdArgs.push_back("-fdeclspec");
5483*67e74705SXin Li   else if (Args.hasArg(options::OPT_fno_declspec))
5484*67e74705SXin Li     CmdArgs.push_back("-fno-declspec"); // Explicitly disabling __declspec.
5485*67e74705SXin Li 
5486*67e74705SXin Li   // -fthreadsafe-static is default, except for MSVC compatibility versions less
5487*67e74705SXin Li   // than 19.
5488*67e74705SXin Li   if (!Args.hasFlag(options::OPT_fthreadsafe_statics,
5489*67e74705SXin Li                     options::OPT_fno_threadsafe_statics,
5490*67e74705SXin Li                     !IsWindowsMSVC || IsMSVC2015Compatible))
5491*67e74705SXin Li     CmdArgs.push_back("-fno-threadsafe-statics");
5492*67e74705SXin Li 
5493*67e74705SXin Li   // -fno-delayed-template-parsing is default, except for Windows where MSVC STL
5494*67e74705SXin Li   // needs it.
5495*67e74705SXin Li   if (Args.hasFlag(options::OPT_fdelayed_template_parsing,
5496*67e74705SXin Li                    options::OPT_fno_delayed_template_parsing, IsWindowsMSVC))
5497*67e74705SXin Li     CmdArgs.push_back("-fdelayed-template-parsing");
5498*67e74705SXin Li 
5499*67e74705SXin Li   // -fgnu-keywords default varies depending on language; only pass if
5500*67e74705SXin Li   // specified.
5501*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_fgnu_keywords,
5502*67e74705SXin Li                                options::OPT_fno_gnu_keywords))
5503*67e74705SXin Li     A->render(Args, CmdArgs);
5504*67e74705SXin Li 
5505*67e74705SXin Li   if (Args.hasFlag(options::OPT_fgnu89_inline, options::OPT_fno_gnu89_inline,
5506*67e74705SXin Li                    false))
5507*67e74705SXin Li     CmdArgs.push_back("-fgnu89-inline");
5508*67e74705SXin Li 
5509*67e74705SXin Li   if (Args.hasArg(options::OPT_fno_inline))
5510*67e74705SXin Li     CmdArgs.push_back("-fno-inline");
5511*67e74705SXin Li 
5512*67e74705SXin Li   if (Arg* InlineArg = Args.getLastArg(options::OPT_finline_functions,
5513*67e74705SXin Li                                        options::OPT_finline_hint_functions,
5514*67e74705SXin Li                                        options::OPT_fno_inline_functions))
5515*67e74705SXin Li     InlineArg->render(Args, CmdArgs);
5516*67e74705SXin Li 
5517*67e74705SXin Li   ObjCRuntime objcRuntime = AddObjCRuntimeArgs(Args, CmdArgs, rewriteKind);
5518*67e74705SXin Li 
5519*67e74705SXin Li   // -fobjc-dispatch-method is only relevant with the nonfragile-abi, and
5520*67e74705SXin Li   // legacy is the default. Except for deployment taget of 10.5,
5521*67e74705SXin Li   // next runtime is always legacy dispatch and -fno-objc-legacy-dispatch
5522*67e74705SXin Li   // gets ignored silently.
5523*67e74705SXin Li   if (objcRuntime.isNonFragile()) {
5524*67e74705SXin Li     if (!Args.hasFlag(options::OPT_fobjc_legacy_dispatch,
5525*67e74705SXin Li                       options::OPT_fno_objc_legacy_dispatch,
5526*67e74705SXin Li                       objcRuntime.isLegacyDispatchDefaultForArch(
5527*67e74705SXin Li                           getToolChain().getArch()))) {
5528*67e74705SXin Li       if (getToolChain().UseObjCMixedDispatch())
5529*67e74705SXin Li         CmdArgs.push_back("-fobjc-dispatch-method=mixed");
5530*67e74705SXin Li       else
5531*67e74705SXin Li         CmdArgs.push_back("-fobjc-dispatch-method=non-legacy");
5532*67e74705SXin Li     }
5533*67e74705SXin Li   }
5534*67e74705SXin Li 
5535*67e74705SXin Li   // When ObjectiveC legacy runtime is in effect on MacOSX,
5536*67e74705SXin Li   // turn on the option to do Array/Dictionary subscripting
5537*67e74705SXin Li   // by default.
5538*67e74705SXin Li   if (getToolChain().getArch() == llvm::Triple::x86 &&
5539*67e74705SXin Li       getToolChain().getTriple().isMacOSX() &&
5540*67e74705SXin Li       !getToolChain().getTriple().isMacOSXVersionLT(10, 7) &&
5541*67e74705SXin Li       objcRuntime.getKind() == ObjCRuntime::FragileMacOSX &&
5542*67e74705SXin Li       objcRuntime.isNeXTFamily())
5543*67e74705SXin Li     CmdArgs.push_back("-fobjc-subscripting-legacy-runtime");
5544*67e74705SXin Li 
5545*67e74705SXin Li   // -fencode-extended-block-signature=1 is default.
5546*67e74705SXin Li   if (getToolChain().IsEncodeExtendedBlockSignatureDefault()) {
5547*67e74705SXin Li     CmdArgs.push_back("-fencode-extended-block-signature");
5548*67e74705SXin Li   }
5549*67e74705SXin Li 
5550*67e74705SXin Li   // Allow -fno-objc-arr to trump -fobjc-arr/-fobjc-arc.
5551*67e74705SXin Li   // NOTE: This logic is duplicated in ToolChains.cpp.
5552*67e74705SXin Li   bool ARC = isObjCAutoRefCount(Args);
5553*67e74705SXin Li   if (ARC) {
5554*67e74705SXin Li     getToolChain().CheckObjCARC();
5555*67e74705SXin Li 
5556*67e74705SXin Li     CmdArgs.push_back("-fobjc-arc");
5557*67e74705SXin Li 
5558*67e74705SXin Li     // FIXME: It seems like this entire block, and several around it should be
5559*67e74705SXin Li     // wrapped in isObjC, but for now we just use it here as this is where it
5560*67e74705SXin Li     // was being used previously.
5561*67e74705SXin Li     if (types::isCXX(InputType) && types::isObjC(InputType)) {
5562*67e74705SXin Li       if (getToolChain().GetCXXStdlibType(Args) == ToolChain::CST_Libcxx)
5563*67e74705SXin Li         CmdArgs.push_back("-fobjc-arc-cxxlib=libc++");
5564*67e74705SXin Li       else
5565*67e74705SXin Li         CmdArgs.push_back("-fobjc-arc-cxxlib=libstdc++");
5566*67e74705SXin Li     }
5567*67e74705SXin Li 
5568*67e74705SXin Li     // Allow the user to enable full exceptions code emission.
5569*67e74705SXin Li     // We define off for Objective-CC, on for Objective-C++.
5570*67e74705SXin Li     if (Args.hasFlag(options::OPT_fobjc_arc_exceptions,
5571*67e74705SXin Li                      options::OPT_fno_objc_arc_exceptions,
5572*67e74705SXin Li                      /*default*/ types::isCXX(InputType)))
5573*67e74705SXin Li       CmdArgs.push_back("-fobjc-arc-exceptions");
5574*67e74705SXin Li 
5575*67e74705SXin Li   }
5576*67e74705SXin Li 
5577*67e74705SXin Li   // -fobjc-infer-related-result-type is the default, except in the Objective-C
5578*67e74705SXin Li   // rewriter.
5579*67e74705SXin Li   if (rewriteKind != RK_None)
5580*67e74705SXin Li     CmdArgs.push_back("-fno-objc-infer-related-result-type");
5581*67e74705SXin Li 
5582*67e74705SXin Li   // Handle -fobjc-gc and -fobjc-gc-only. They are exclusive, and -fobjc-gc-only
5583*67e74705SXin Li   // takes precedence.
5584*67e74705SXin Li   const Arg *GCArg = Args.getLastArg(options::OPT_fobjc_gc_only);
5585*67e74705SXin Li   if (!GCArg)
5586*67e74705SXin Li     GCArg = Args.getLastArg(options::OPT_fobjc_gc);
5587*67e74705SXin Li   if (GCArg) {
5588*67e74705SXin Li     if (ARC) {
5589*67e74705SXin Li       D.Diag(diag::err_drv_objc_gc_arr) << GCArg->getAsString(Args);
5590*67e74705SXin Li     } else if (getToolChain().SupportsObjCGC()) {
5591*67e74705SXin Li       GCArg->render(Args, CmdArgs);
5592*67e74705SXin Li     } else {
5593*67e74705SXin Li       // FIXME: We should move this to a hard error.
5594*67e74705SXin Li       D.Diag(diag::warn_drv_objc_gc_unsupported) << GCArg->getAsString(Args);
5595*67e74705SXin Li     }
5596*67e74705SXin Li   }
5597*67e74705SXin Li 
5598*67e74705SXin Li   // Pass down -fobjc-weak or -fno-objc-weak if present.
5599*67e74705SXin Li   if (types::isObjC(InputType)) {
5600*67e74705SXin Li     auto WeakArg = Args.getLastArg(options::OPT_fobjc_weak,
5601*67e74705SXin Li                                    options::OPT_fno_objc_weak);
5602*67e74705SXin Li     if (!WeakArg) {
5603*67e74705SXin Li       // nothing to do
5604*67e74705SXin Li     } else if (GCArg) {
5605*67e74705SXin Li       if (WeakArg->getOption().matches(options::OPT_fobjc_weak))
5606*67e74705SXin Li         D.Diag(diag::err_objc_weak_with_gc);
5607*67e74705SXin Li     } else if (!objcRuntime.allowsWeak()) {
5608*67e74705SXin Li       if (WeakArg->getOption().matches(options::OPT_fobjc_weak))
5609*67e74705SXin Li         D.Diag(diag::err_objc_weak_unsupported);
5610*67e74705SXin Li     } else {
5611*67e74705SXin Li       WeakArg->render(Args, CmdArgs);
5612*67e74705SXin Li     }
5613*67e74705SXin Li   }
5614*67e74705SXin Li 
5615*67e74705SXin Li   if (Args.hasFlag(options::OPT_fapplication_extension,
5616*67e74705SXin Li                    options::OPT_fno_application_extension, false))
5617*67e74705SXin Li     CmdArgs.push_back("-fapplication-extension");
5618*67e74705SXin Li 
5619*67e74705SXin Li   // Handle GCC-style exception args.
5620*67e74705SXin Li   if (!C.getDriver().IsCLMode())
5621*67e74705SXin Li     addExceptionArgs(Args, InputType, getToolChain(), KernelOrKext, objcRuntime,
5622*67e74705SXin Li                      CmdArgs);
5623*67e74705SXin Li 
5624*67e74705SXin Li   if (Args.hasArg(options::OPT_fsjlj_exceptions) ||
5625*67e74705SXin Li       getToolChain().UseSjLjExceptions(Args))
5626*67e74705SXin Li     CmdArgs.push_back("-fsjlj-exceptions");
5627*67e74705SXin Li 
5628*67e74705SXin Li   // C++ "sane" operator new.
5629*67e74705SXin Li   if (!Args.hasFlag(options::OPT_fassume_sane_operator_new,
5630*67e74705SXin Li                     options::OPT_fno_assume_sane_operator_new))
5631*67e74705SXin Li     CmdArgs.push_back("-fno-assume-sane-operator-new");
5632*67e74705SXin Li 
5633*67e74705SXin Li   // -fsized-deallocation is off by default, as it is an ABI-breaking change for
5634*67e74705SXin Li   // most platforms.
5635*67e74705SXin Li   if (Args.hasFlag(options::OPT_fsized_deallocation,
5636*67e74705SXin Li                    options::OPT_fno_sized_deallocation, false))
5637*67e74705SXin Li     CmdArgs.push_back("-fsized-deallocation");
5638*67e74705SXin Li 
5639*67e74705SXin Li   // -fconstant-cfstrings is default, and may be subject to argument translation
5640*67e74705SXin Li   // on Darwin.
5641*67e74705SXin Li   if (!Args.hasFlag(options::OPT_fconstant_cfstrings,
5642*67e74705SXin Li                     options::OPT_fno_constant_cfstrings) ||
5643*67e74705SXin Li       !Args.hasFlag(options::OPT_mconstant_cfstrings,
5644*67e74705SXin Li                     options::OPT_mno_constant_cfstrings))
5645*67e74705SXin Li     CmdArgs.push_back("-fno-constant-cfstrings");
5646*67e74705SXin Li 
5647*67e74705SXin Li   // -fshort-wchar default varies depending on platform; only
5648*67e74705SXin Li   // pass if specified.
5649*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_fshort_wchar,
5650*67e74705SXin Li                                options::OPT_fno_short_wchar))
5651*67e74705SXin Li     A->render(Args, CmdArgs);
5652*67e74705SXin Li 
5653*67e74705SXin Li   // -fno-pascal-strings is default, only pass non-default.
5654*67e74705SXin Li   if (Args.hasFlag(options::OPT_fpascal_strings,
5655*67e74705SXin Li                    options::OPT_fno_pascal_strings, false))
5656*67e74705SXin Li     CmdArgs.push_back("-fpascal-strings");
5657*67e74705SXin Li 
5658*67e74705SXin Li   // Honor -fpack-struct= and -fpack-struct, if given. Note that
5659*67e74705SXin Li   // -fno-pack-struct doesn't apply to -fpack-struct=.
5660*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_fpack_struct_EQ)) {
5661*67e74705SXin Li     std::string PackStructStr = "-fpack-struct=";
5662*67e74705SXin Li     PackStructStr += A->getValue();
5663*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(PackStructStr));
5664*67e74705SXin Li   } else if (Args.hasFlag(options::OPT_fpack_struct,
5665*67e74705SXin Li                           options::OPT_fno_pack_struct, false)) {
5666*67e74705SXin Li     CmdArgs.push_back("-fpack-struct=1");
5667*67e74705SXin Li   }
5668*67e74705SXin Li 
5669*67e74705SXin Li   // Handle -fmax-type-align=N and -fno-type-align
5670*67e74705SXin Li   bool SkipMaxTypeAlign = Args.hasArg(options::OPT_fno_max_type_align);
5671*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_fmax_type_align_EQ)) {
5672*67e74705SXin Li     if (!SkipMaxTypeAlign) {
5673*67e74705SXin Li       std::string MaxTypeAlignStr = "-fmax-type-align=";
5674*67e74705SXin Li       MaxTypeAlignStr += A->getValue();
5675*67e74705SXin Li       CmdArgs.push_back(Args.MakeArgString(MaxTypeAlignStr));
5676*67e74705SXin Li     }
5677*67e74705SXin Li   } else if (getToolChain().getTriple().isOSDarwin()) {
5678*67e74705SXin Li     if (!SkipMaxTypeAlign) {
5679*67e74705SXin Li       std::string MaxTypeAlignStr = "-fmax-type-align=16";
5680*67e74705SXin Li       CmdArgs.push_back(Args.MakeArgString(MaxTypeAlignStr));
5681*67e74705SXin Li     }
5682*67e74705SXin Li   }
5683*67e74705SXin Li 
5684*67e74705SXin Li   // -fcommon is the default unless compiling kernel code or the target says so
5685*67e74705SXin Li   bool NoCommonDefault =
5686*67e74705SXin Li       KernelOrKext || isNoCommonDefault(getToolChain().getTriple());
5687*67e74705SXin Li   if (!Args.hasFlag(options::OPT_fcommon, options::OPT_fno_common,
5688*67e74705SXin Li                     !NoCommonDefault))
5689*67e74705SXin Li     CmdArgs.push_back("-fno-common");
5690*67e74705SXin Li 
5691*67e74705SXin Li   // -fsigned-bitfields is default, and clang doesn't yet support
5692*67e74705SXin Li   // -funsigned-bitfields.
5693*67e74705SXin Li   if (!Args.hasFlag(options::OPT_fsigned_bitfields,
5694*67e74705SXin Li                     options::OPT_funsigned_bitfields))
5695*67e74705SXin Li     D.Diag(diag::warn_drv_clang_unsupported)
5696*67e74705SXin Li         << Args.getLastArg(options::OPT_funsigned_bitfields)->getAsString(Args);
5697*67e74705SXin Li 
5698*67e74705SXin Li   // -fsigned-bitfields is default, and clang doesn't support -fno-for-scope.
5699*67e74705SXin Li   if (!Args.hasFlag(options::OPT_ffor_scope, options::OPT_fno_for_scope))
5700*67e74705SXin Li     D.Diag(diag::err_drv_clang_unsupported)
5701*67e74705SXin Li         << Args.getLastArg(options::OPT_fno_for_scope)->getAsString(Args);
5702*67e74705SXin Li 
5703*67e74705SXin Li   // -finput_charset=UTF-8 is default. Reject others
5704*67e74705SXin Li   if (Arg *inputCharset = Args.getLastArg(options::OPT_finput_charset_EQ)) {
5705*67e74705SXin Li     StringRef value = inputCharset->getValue();
5706*67e74705SXin Li     if (value != "UTF-8")
5707*67e74705SXin Li       D.Diag(diag::err_drv_invalid_value) << inputCharset->getAsString(Args)
5708*67e74705SXin Li                                           << value;
5709*67e74705SXin Li   }
5710*67e74705SXin Li 
5711*67e74705SXin Li   // -fexec_charset=UTF-8 is default. Reject others
5712*67e74705SXin Li   if (Arg *execCharset = Args.getLastArg(options::OPT_fexec_charset_EQ)) {
5713*67e74705SXin Li     StringRef value = execCharset->getValue();
5714*67e74705SXin Li     if (value != "UTF-8")
5715*67e74705SXin Li       D.Diag(diag::err_drv_invalid_value) << execCharset->getAsString(Args)
5716*67e74705SXin Li                                           << value;
5717*67e74705SXin Li   }
5718*67e74705SXin Li 
5719*67e74705SXin Li   // -fcaret-diagnostics is default.
5720*67e74705SXin Li   if (!Args.hasFlag(options::OPT_fcaret_diagnostics,
5721*67e74705SXin Li                     options::OPT_fno_caret_diagnostics, true))
5722*67e74705SXin Li     CmdArgs.push_back("-fno-caret-diagnostics");
5723*67e74705SXin Li 
5724*67e74705SXin Li   // -fdiagnostics-fixit-info is default, only pass non-default.
5725*67e74705SXin Li   if (!Args.hasFlag(options::OPT_fdiagnostics_fixit_info,
5726*67e74705SXin Li                     options::OPT_fno_diagnostics_fixit_info))
5727*67e74705SXin Li     CmdArgs.push_back("-fno-diagnostics-fixit-info");
5728*67e74705SXin Li 
5729*67e74705SXin Li   // Enable -fdiagnostics-show-option by default.
5730*67e74705SXin Li   if (Args.hasFlag(options::OPT_fdiagnostics_show_option,
5731*67e74705SXin Li                    options::OPT_fno_diagnostics_show_option))
5732*67e74705SXin Li     CmdArgs.push_back("-fdiagnostics-show-option");
5733*67e74705SXin Li 
5734*67e74705SXin Li   if (const Arg *A =
5735*67e74705SXin Li           Args.getLastArg(options::OPT_fdiagnostics_show_category_EQ)) {
5736*67e74705SXin Li     CmdArgs.push_back("-fdiagnostics-show-category");
5737*67e74705SXin Li     CmdArgs.push_back(A->getValue());
5738*67e74705SXin Li   }
5739*67e74705SXin Li 
5740*67e74705SXin Li   if (const Arg *A = Args.getLastArg(options::OPT_fdiagnostics_format_EQ)) {
5741*67e74705SXin Li     CmdArgs.push_back("-fdiagnostics-format");
5742*67e74705SXin Li     CmdArgs.push_back(A->getValue());
5743*67e74705SXin Li   }
5744*67e74705SXin Li 
5745*67e74705SXin Li   if (Arg *A = Args.getLastArg(
5746*67e74705SXin Li           options::OPT_fdiagnostics_show_note_include_stack,
5747*67e74705SXin Li           options::OPT_fno_diagnostics_show_note_include_stack)) {
5748*67e74705SXin Li     if (A->getOption().matches(
5749*67e74705SXin Li             options::OPT_fdiagnostics_show_note_include_stack))
5750*67e74705SXin Li       CmdArgs.push_back("-fdiagnostics-show-note-include-stack");
5751*67e74705SXin Li     else
5752*67e74705SXin Li       CmdArgs.push_back("-fno-diagnostics-show-note-include-stack");
5753*67e74705SXin Li   }
5754*67e74705SXin Li 
5755*67e74705SXin Li   // Color diagnostics are parsed by the driver directly from argv
5756*67e74705SXin Li   // and later re-parsed to construct this job; claim any possible
5757*67e74705SXin Li   // color diagnostic here to avoid warn_drv_unused_argument and
5758*67e74705SXin Li   // diagnose bad OPT_fdiagnostics_color_EQ values.
5759*67e74705SXin Li   for (Arg *A : Args) {
5760*67e74705SXin Li     const Option &O = A->getOption();
5761*67e74705SXin Li     if (!O.matches(options::OPT_fcolor_diagnostics) &&
5762*67e74705SXin Li         !O.matches(options::OPT_fdiagnostics_color) &&
5763*67e74705SXin Li         !O.matches(options::OPT_fno_color_diagnostics) &&
5764*67e74705SXin Li         !O.matches(options::OPT_fno_diagnostics_color) &&
5765*67e74705SXin Li         !O.matches(options::OPT_fdiagnostics_color_EQ))
5766*67e74705SXin Li       continue;
5767*67e74705SXin Li     if (O.matches(options::OPT_fdiagnostics_color_EQ)) {
5768*67e74705SXin Li       StringRef Value(A->getValue());
5769*67e74705SXin Li       if (Value != "always" && Value != "never" && Value != "auto")
5770*67e74705SXin Li         getToolChain().getDriver().Diag(diag::err_drv_clang_unsupported)
5771*67e74705SXin Li               << ("-fdiagnostics-color=" + Value).str();
5772*67e74705SXin Li     }
5773*67e74705SXin Li     A->claim();
5774*67e74705SXin Li   }
5775*67e74705SXin Li   if (D.getDiags().getDiagnosticOptions().ShowColors)
5776*67e74705SXin Li     CmdArgs.push_back("-fcolor-diagnostics");
5777*67e74705SXin Li 
5778*67e74705SXin Li   if (Args.hasArg(options::OPT_fansi_escape_codes))
5779*67e74705SXin Li     CmdArgs.push_back("-fansi-escape-codes");
5780*67e74705SXin Li 
5781*67e74705SXin Li   if (!Args.hasFlag(options::OPT_fshow_source_location,
5782*67e74705SXin Li                     options::OPT_fno_show_source_location))
5783*67e74705SXin Li     CmdArgs.push_back("-fno-show-source-location");
5784*67e74705SXin Li 
5785*67e74705SXin Li   if (!Args.hasFlag(options::OPT_fshow_column, options::OPT_fno_show_column,
5786*67e74705SXin Li                     true))
5787*67e74705SXin Li     CmdArgs.push_back("-fno-show-column");
5788*67e74705SXin Li 
5789*67e74705SXin Li   if (!Args.hasFlag(options::OPT_fspell_checking,
5790*67e74705SXin Li                     options::OPT_fno_spell_checking))
5791*67e74705SXin Li     CmdArgs.push_back("-fno-spell-checking");
5792*67e74705SXin Li 
5793*67e74705SXin Li   // -fno-asm-blocks is default.
5794*67e74705SXin Li   if (Args.hasFlag(options::OPT_fasm_blocks, options::OPT_fno_asm_blocks,
5795*67e74705SXin Li                    false))
5796*67e74705SXin Li     CmdArgs.push_back("-fasm-blocks");
5797*67e74705SXin Li 
5798*67e74705SXin Li   // -fgnu-inline-asm is default.
5799*67e74705SXin Li   if (!Args.hasFlag(options::OPT_fgnu_inline_asm,
5800*67e74705SXin Li                     options::OPT_fno_gnu_inline_asm, true))
5801*67e74705SXin Li     CmdArgs.push_back("-fno-gnu-inline-asm");
5802*67e74705SXin Li 
5803*67e74705SXin Li   // Enable vectorization per default according to the optimization level
5804*67e74705SXin Li   // selected. For optimization levels that want vectorization we use the alias
5805*67e74705SXin Li   // option to simplify the hasFlag logic.
5806*67e74705SXin Li   bool EnableVec = shouldEnableVectorizerAtOLevel(Args, false);
5807*67e74705SXin Li   OptSpecifier VectorizeAliasOption =
5808*67e74705SXin Li       EnableVec ? options::OPT_O_Group : options::OPT_fvectorize;
5809*67e74705SXin Li   if (Args.hasFlag(options::OPT_fvectorize, VectorizeAliasOption,
5810*67e74705SXin Li                    options::OPT_fno_vectorize, EnableVec))
5811*67e74705SXin Li     CmdArgs.push_back("-vectorize-loops");
5812*67e74705SXin Li 
5813*67e74705SXin Li   // -fslp-vectorize is enabled based on the optimization level selected.
5814*67e74705SXin Li   bool EnableSLPVec = shouldEnableVectorizerAtOLevel(Args, true);
5815*67e74705SXin Li   OptSpecifier SLPVectAliasOption =
5816*67e74705SXin Li       EnableSLPVec ? options::OPT_O_Group : options::OPT_fslp_vectorize;
5817*67e74705SXin Li   if (Args.hasFlag(options::OPT_fslp_vectorize, SLPVectAliasOption,
5818*67e74705SXin Li                    options::OPT_fno_slp_vectorize, EnableSLPVec))
5819*67e74705SXin Li     CmdArgs.push_back("-vectorize-slp");
5820*67e74705SXin Li 
5821*67e74705SXin Li   // -fno-slp-vectorize-aggressive is default.
5822*67e74705SXin Li   if (Args.hasFlag(options::OPT_fslp_vectorize_aggressive,
5823*67e74705SXin Li                    options::OPT_fno_slp_vectorize_aggressive, false))
5824*67e74705SXin Li     CmdArgs.push_back("-vectorize-slp-aggressive");
5825*67e74705SXin Li 
5826*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_fshow_overloads_EQ))
5827*67e74705SXin Li     A->render(Args, CmdArgs);
5828*67e74705SXin Li 
5829*67e74705SXin Li   if (Arg *A = Args.getLastArg(
5830*67e74705SXin Li           options::OPT_fsanitize_undefined_strip_path_components_EQ))
5831*67e74705SXin Li     A->render(Args, CmdArgs);
5832*67e74705SXin Li 
5833*67e74705SXin Li   // -fdollars-in-identifiers default varies depending on platform and
5834*67e74705SXin Li   // language; only pass if specified.
5835*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_fdollars_in_identifiers,
5836*67e74705SXin Li                                options::OPT_fno_dollars_in_identifiers)) {
5837*67e74705SXin Li     if (A->getOption().matches(options::OPT_fdollars_in_identifiers))
5838*67e74705SXin Li       CmdArgs.push_back("-fdollars-in-identifiers");
5839*67e74705SXin Li     else
5840*67e74705SXin Li       CmdArgs.push_back("-fno-dollars-in-identifiers");
5841*67e74705SXin Li   }
5842*67e74705SXin Li 
5843*67e74705SXin Li   // -funit-at-a-time is default, and we don't support -fno-unit-at-a-time for
5844*67e74705SXin Li   // practical purposes.
5845*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_funit_at_a_time,
5846*67e74705SXin Li                                options::OPT_fno_unit_at_a_time)) {
5847*67e74705SXin Li     if (A->getOption().matches(options::OPT_fno_unit_at_a_time))
5848*67e74705SXin Li       D.Diag(diag::warn_drv_clang_unsupported) << A->getAsString(Args);
5849*67e74705SXin Li   }
5850*67e74705SXin Li 
5851*67e74705SXin Li   if (Args.hasFlag(options::OPT_fapple_pragma_pack,
5852*67e74705SXin Li                    options::OPT_fno_apple_pragma_pack, false))
5853*67e74705SXin Li     CmdArgs.push_back("-fapple-pragma-pack");
5854*67e74705SXin Li 
5855*67e74705SXin Li   // le32-specific flags:
5856*67e74705SXin Li   //  -fno-math-builtin: clang should not convert math builtins to intrinsics
5857*67e74705SXin Li   //                     by default.
5858*67e74705SXin Li   if (getToolChain().getArch() == llvm::Triple::le32) {
5859*67e74705SXin Li     CmdArgs.push_back("-fno-math-builtin");
5860*67e74705SXin Li   }
5861*67e74705SXin Li 
5862*67e74705SXin Li // Default to -fno-builtin-str{cat,cpy} on Darwin for ARM.
5863*67e74705SXin Li //
5864*67e74705SXin Li // FIXME: Now that PR4941 has been fixed this can be enabled.
5865*67e74705SXin Li #if 0
5866*67e74705SXin Li   if (getToolChain().getTriple().isOSDarwin() &&
5867*67e74705SXin Li       (getToolChain().getArch() == llvm::Triple::arm ||
5868*67e74705SXin Li        getToolChain().getArch() == llvm::Triple::thumb)) {
5869*67e74705SXin Li     if (!Args.hasArg(options::OPT_fbuiltin_strcat))
5870*67e74705SXin Li       CmdArgs.push_back("-fno-builtin-strcat");
5871*67e74705SXin Li     if (!Args.hasArg(options::OPT_fbuiltin_strcpy))
5872*67e74705SXin Li       CmdArgs.push_back("-fno-builtin-strcpy");
5873*67e74705SXin Li   }
5874*67e74705SXin Li #endif
5875*67e74705SXin Li 
5876*67e74705SXin Li   // Enable rewrite includes if the user's asked for it or if we're generating
5877*67e74705SXin Li   // diagnostics.
5878*67e74705SXin Li   // TODO: Once -module-dependency-dir works with -frewrite-includes it'd be
5879*67e74705SXin Li   // nice to enable this when doing a crashdump for modules as well.
5880*67e74705SXin Li   if (Args.hasFlag(options::OPT_frewrite_includes,
5881*67e74705SXin Li                    options::OPT_fno_rewrite_includes, false) ||
5882*67e74705SXin Li       (C.isForDiagnostics() && !HaveModules))
5883*67e74705SXin Li     CmdArgs.push_back("-frewrite-includes");
5884*67e74705SXin Li 
5885*67e74705SXin Li   // Only allow -traditional or -traditional-cpp outside in preprocessing modes.
5886*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_traditional,
5887*67e74705SXin Li                                options::OPT_traditional_cpp)) {
5888*67e74705SXin Li     if (isa<PreprocessJobAction>(JA))
5889*67e74705SXin Li       CmdArgs.push_back("-traditional-cpp");
5890*67e74705SXin Li     else
5891*67e74705SXin Li       D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
5892*67e74705SXin Li   }
5893*67e74705SXin Li 
5894*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_dM);
5895*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_dD);
5896*67e74705SXin Li 
5897*67e74705SXin Li   // Handle serialized diagnostics.
5898*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT__serialize_diags)) {
5899*67e74705SXin Li     CmdArgs.push_back("-serialize-diagnostic-file");
5900*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(A->getValue()));
5901*67e74705SXin Li   }
5902*67e74705SXin Li 
5903*67e74705SXin Li   if (Args.hasArg(options::OPT_fretain_comments_from_system_headers))
5904*67e74705SXin Li     CmdArgs.push_back("-fretain-comments-from-system-headers");
5905*67e74705SXin Li 
5906*67e74705SXin Li   // Forward -fcomment-block-commands to -cc1.
5907*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_fcomment_block_commands);
5908*67e74705SXin Li   // Forward -fparse-all-comments to -cc1.
5909*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_fparse_all_comments);
5910*67e74705SXin Li 
5911*67e74705SXin Li   // Turn -fplugin=name.so into -load name.so
5912*67e74705SXin Li   for (const Arg *A : Args.filtered(options::OPT_fplugin_EQ)) {
5913*67e74705SXin Li     CmdArgs.push_back("-load");
5914*67e74705SXin Li     CmdArgs.push_back(A->getValue());
5915*67e74705SXin Li     A->claim();
5916*67e74705SXin Li   }
5917*67e74705SXin Li 
5918*67e74705SXin Li   // Forward -Xclang arguments to -cc1, and -mllvm arguments to the LLVM option
5919*67e74705SXin Li   // parser.
5920*67e74705SXin Li   Args.AddAllArgValues(CmdArgs, options::OPT_Xclang);
5921*67e74705SXin Li   for (const Arg *A : Args.filtered(options::OPT_mllvm)) {
5922*67e74705SXin Li     A->claim();
5923*67e74705SXin Li 
5924*67e74705SXin Li     // We translate this by hand to the -cc1 argument, since nightly test uses
5925*67e74705SXin Li     // it and developers have been trained to spell it with -mllvm.
5926*67e74705SXin Li     if (StringRef(A->getValue(0)) == "-disable-llvm-optzns") {
5927*67e74705SXin Li       CmdArgs.push_back("-disable-llvm-optzns");
5928*67e74705SXin Li     } else
5929*67e74705SXin Li       A->render(Args, CmdArgs);
5930*67e74705SXin Li   }
5931*67e74705SXin Li 
5932*67e74705SXin Li   // With -save-temps, we want to save the unoptimized bitcode output from the
5933*67e74705SXin Li   // CompileJobAction, use -disable-llvm-passes to get pristine IR generated
5934*67e74705SXin Li   // by the frontend.
5935*67e74705SXin Li   // When -fembed-bitcode is enabled, optimized bitcode is emitted because it
5936*67e74705SXin Li   // has slightly different breakdown between stages.
5937*67e74705SXin Li   // FIXME: -fembed-bitcode -save-temps will save optimized bitcode instead of
5938*67e74705SXin Li   // pristine IR generated by the frontend. Ideally, a new compile action should
5939*67e74705SXin Li   // be added so both IR can be captured.
5940*67e74705SXin Li   if (C.getDriver().isSaveTempsEnabled() &&
5941*67e74705SXin Li       !C.getDriver().embedBitcodeEnabled() && isa<CompileJobAction>(JA))
5942*67e74705SXin Li     CmdArgs.push_back("-disable-llvm-passes");
5943*67e74705SXin Li 
5944*67e74705SXin Li   if (Output.getType() == types::TY_Dependencies) {
5945*67e74705SXin Li     // Handled with other dependency code.
5946*67e74705SXin Li   } else if (Output.isFilename()) {
5947*67e74705SXin Li     CmdArgs.push_back("-o");
5948*67e74705SXin Li     CmdArgs.push_back(Output.getFilename());
5949*67e74705SXin Li   } else {
5950*67e74705SXin Li     assert(Output.isNothing() && "Invalid output.");
5951*67e74705SXin Li   }
5952*67e74705SXin Li 
5953*67e74705SXin Li   addDashXForInput(Args, Input, CmdArgs);
5954*67e74705SXin Li 
5955*67e74705SXin Li   if (Input.isFilename())
5956*67e74705SXin Li     CmdArgs.push_back(Input.getFilename());
5957*67e74705SXin Li   else
5958*67e74705SXin Li     Input.getInputArg().renderAsInput(Args, CmdArgs);
5959*67e74705SXin Li 
5960*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_undef);
5961*67e74705SXin Li 
5962*67e74705SXin Li   const char *Exec = getToolChain().getDriver().getClangProgramPath();
5963*67e74705SXin Li 
5964*67e74705SXin Li   // Optionally embed the -cc1 level arguments into the debug info, for build
5965*67e74705SXin Li   // analysis.
5966*67e74705SXin Li   if (getToolChain().UseDwarfDebugFlags()) {
5967*67e74705SXin Li     ArgStringList OriginalArgs;
5968*67e74705SXin Li     for (const auto &Arg : Args)
5969*67e74705SXin Li       Arg->render(Args, OriginalArgs);
5970*67e74705SXin Li 
5971*67e74705SXin Li     SmallString<256> Flags;
5972*67e74705SXin Li     Flags += Exec;
5973*67e74705SXin Li     for (const char *OriginalArg : OriginalArgs) {
5974*67e74705SXin Li       SmallString<128> EscapedArg;
5975*67e74705SXin Li       EscapeSpacesAndBackslashes(OriginalArg, EscapedArg);
5976*67e74705SXin Li       Flags += " ";
5977*67e74705SXin Li       Flags += EscapedArg;
5978*67e74705SXin Li     }
5979*67e74705SXin Li     CmdArgs.push_back("-dwarf-debug-flags");
5980*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(Flags));
5981*67e74705SXin Li   }
5982*67e74705SXin Li 
5983*67e74705SXin Li   // Add the split debug info name to the command lines here so we
5984*67e74705SXin Li   // can propagate it to the backend.
5985*67e74705SXin Li   bool SplitDwarf = SplitDwarfArg && getToolChain().getTriple().isOSLinux() &&
5986*67e74705SXin Li                     (isa<AssembleJobAction>(JA) || isa<CompileJobAction>(JA) ||
5987*67e74705SXin Li                      isa<BackendJobAction>(JA));
5988*67e74705SXin Li   const char *SplitDwarfOut;
5989*67e74705SXin Li   if (SplitDwarf) {
5990*67e74705SXin Li     CmdArgs.push_back("-split-dwarf-file");
5991*67e74705SXin Li     SplitDwarfOut = SplitDebugName(Args, Input);
5992*67e74705SXin Li     CmdArgs.push_back(SplitDwarfOut);
5993*67e74705SXin Li   }
5994*67e74705SXin Li 
5995*67e74705SXin Li   // Host-side cuda compilation receives device-side outputs as Inputs[1...].
5996*67e74705SXin Li   // Include them with -fcuda-include-gpubinary.
5997*67e74705SXin Li   if (IsCuda && Inputs.size() > 1)
5998*67e74705SXin Li     for (auto I = std::next(Inputs.begin()), E = Inputs.end(); I != E; ++I) {
5999*67e74705SXin Li       CmdArgs.push_back("-fcuda-include-gpubinary");
6000*67e74705SXin Li       CmdArgs.push_back(I->getFilename());
6001*67e74705SXin Li     }
6002*67e74705SXin Li 
6003*67e74705SXin Li   bool WholeProgramVTables =
6004*67e74705SXin Li       Args.hasFlag(options::OPT_fwhole_program_vtables,
6005*67e74705SXin Li                    options::OPT_fno_whole_program_vtables, false);
6006*67e74705SXin Li   if (WholeProgramVTables) {
6007*67e74705SXin Li     if (!D.isUsingLTO())
6008*67e74705SXin Li       D.Diag(diag::err_drv_argument_only_allowed_with)
6009*67e74705SXin Li           << "-fwhole-program-vtables"
6010*67e74705SXin Li           << "-flto";
6011*67e74705SXin Li     CmdArgs.push_back("-fwhole-program-vtables");
6012*67e74705SXin Li   }
6013*67e74705SXin Li 
6014*67e74705SXin Li   // Finally add the compile command to the compilation.
6015*67e74705SXin Li   if (Args.hasArg(options::OPT__SLASH_fallback) &&
6016*67e74705SXin Li       Output.getType() == types::TY_Object &&
6017*67e74705SXin Li       (InputType == types::TY_C || InputType == types::TY_CXX)) {
6018*67e74705SXin Li     auto CLCommand =
6019*67e74705SXin Li         getCLFallback()->GetCommand(C, JA, Output, Inputs, Args, LinkingOutput);
6020*67e74705SXin Li     C.addCommand(llvm::make_unique<FallbackCommand>(
6021*67e74705SXin Li         JA, *this, Exec, CmdArgs, Inputs, std::move(CLCommand)));
6022*67e74705SXin Li   } else if (Args.hasArg(options::OPT__SLASH_fallback) &&
6023*67e74705SXin Li              isa<PrecompileJobAction>(JA)) {
6024*67e74705SXin Li     // In /fallback builds, run the main compilation even if the pch generation
6025*67e74705SXin Li     // fails, so that the main compilation's fallback to cl.exe runs.
6026*67e74705SXin Li     C.addCommand(llvm::make_unique<ForceSuccessCommand>(JA, *this, Exec,
6027*67e74705SXin Li                                                         CmdArgs, Inputs));
6028*67e74705SXin Li   } else {
6029*67e74705SXin Li     C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
6030*67e74705SXin Li   }
6031*67e74705SXin Li 
6032*67e74705SXin Li   // Handle the debug info splitting at object creation time if we're
6033*67e74705SXin Li   // creating an object.
6034*67e74705SXin Li   // TODO: Currently only works on linux with newer objcopy.
6035*67e74705SXin Li   if (SplitDwarf && Output.getType() == types::TY_Object)
6036*67e74705SXin Li     SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output, SplitDwarfOut);
6037*67e74705SXin Li 
6038*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_pg))
6039*67e74705SXin Li     if (Args.hasArg(options::OPT_fomit_frame_pointer))
6040*67e74705SXin Li       D.Diag(diag::err_drv_argument_not_allowed_with) << "-fomit-frame-pointer"
6041*67e74705SXin Li                                                       << A->getAsString(Args);
6042*67e74705SXin Li 
6043*67e74705SXin Li   // Claim some arguments which clang supports automatically.
6044*67e74705SXin Li 
6045*67e74705SXin Li   // -fpch-preprocess is used with gcc to add a special marker in the output to
6046*67e74705SXin Li   // include the PCH file. Clang's PTH solution is completely transparent, so we
6047*67e74705SXin Li   // do not need to deal with it at all.
6048*67e74705SXin Li   Args.ClaimAllArgs(options::OPT_fpch_preprocess);
6049*67e74705SXin Li 
6050*67e74705SXin Li   // Claim some arguments which clang doesn't support, but we don't
6051*67e74705SXin Li   // care to warn the user about.
6052*67e74705SXin Li   Args.ClaimAllArgs(options::OPT_clang_ignored_f_Group);
6053*67e74705SXin Li   Args.ClaimAllArgs(options::OPT_clang_ignored_m_Group);
6054*67e74705SXin Li 
6055*67e74705SXin Li   // Disable warnings for clang -E -emit-llvm foo.c
6056*67e74705SXin Li   Args.ClaimAllArgs(options::OPT_emit_llvm);
6057*67e74705SXin Li }
6058*67e74705SXin Li 
6059*67e74705SXin Li /// Add options related to the Objective-C runtime/ABI.
6060*67e74705SXin Li ///
6061*67e74705SXin Li /// Returns true if the runtime is non-fragile.
AddObjCRuntimeArgs(const ArgList & args,ArgStringList & cmdArgs,RewriteKind rewriteKind) const6062*67e74705SXin Li ObjCRuntime Clang::AddObjCRuntimeArgs(const ArgList &args,
6063*67e74705SXin Li                                       ArgStringList &cmdArgs,
6064*67e74705SXin Li                                       RewriteKind rewriteKind) const {
6065*67e74705SXin Li   // Look for the controlling runtime option.
6066*67e74705SXin Li   Arg *runtimeArg =
6067*67e74705SXin Li       args.getLastArg(options::OPT_fnext_runtime, options::OPT_fgnu_runtime,
6068*67e74705SXin Li                       options::OPT_fobjc_runtime_EQ);
6069*67e74705SXin Li 
6070*67e74705SXin Li   // Just forward -fobjc-runtime= to the frontend.  This supercedes
6071*67e74705SXin Li   // options about fragility.
6072*67e74705SXin Li   if (runtimeArg &&
6073*67e74705SXin Li       runtimeArg->getOption().matches(options::OPT_fobjc_runtime_EQ)) {
6074*67e74705SXin Li     ObjCRuntime runtime;
6075*67e74705SXin Li     StringRef value = runtimeArg->getValue();
6076*67e74705SXin Li     if (runtime.tryParse(value)) {
6077*67e74705SXin Li       getToolChain().getDriver().Diag(diag::err_drv_unknown_objc_runtime)
6078*67e74705SXin Li           << value;
6079*67e74705SXin Li     }
6080*67e74705SXin Li 
6081*67e74705SXin Li     runtimeArg->render(args, cmdArgs);
6082*67e74705SXin Li     return runtime;
6083*67e74705SXin Li   }
6084*67e74705SXin Li 
6085*67e74705SXin Li   // Otherwise, we'll need the ABI "version".  Version numbers are
6086*67e74705SXin Li   // slightly confusing for historical reasons:
6087*67e74705SXin Li   //   1 - Traditional "fragile" ABI
6088*67e74705SXin Li   //   2 - Non-fragile ABI, version 1
6089*67e74705SXin Li   //   3 - Non-fragile ABI, version 2
6090*67e74705SXin Li   unsigned objcABIVersion = 1;
6091*67e74705SXin Li   // If -fobjc-abi-version= is present, use that to set the version.
6092*67e74705SXin Li   if (Arg *abiArg = args.getLastArg(options::OPT_fobjc_abi_version_EQ)) {
6093*67e74705SXin Li     StringRef value = abiArg->getValue();
6094*67e74705SXin Li     if (value == "1")
6095*67e74705SXin Li       objcABIVersion = 1;
6096*67e74705SXin Li     else if (value == "2")
6097*67e74705SXin Li       objcABIVersion = 2;
6098*67e74705SXin Li     else if (value == "3")
6099*67e74705SXin Li       objcABIVersion = 3;
6100*67e74705SXin Li     else
6101*67e74705SXin Li       getToolChain().getDriver().Diag(diag::err_drv_clang_unsupported) << value;
6102*67e74705SXin Li   } else {
6103*67e74705SXin Li     // Otherwise, determine if we are using the non-fragile ABI.
6104*67e74705SXin Li     bool nonFragileABIIsDefault =
6105*67e74705SXin Li         (rewriteKind == RK_NonFragile ||
6106*67e74705SXin Li          (rewriteKind == RK_None &&
6107*67e74705SXin Li           getToolChain().IsObjCNonFragileABIDefault()));
6108*67e74705SXin Li     if (args.hasFlag(options::OPT_fobjc_nonfragile_abi,
6109*67e74705SXin Li                      options::OPT_fno_objc_nonfragile_abi,
6110*67e74705SXin Li                      nonFragileABIIsDefault)) {
6111*67e74705SXin Li // Determine the non-fragile ABI version to use.
6112*67e74705SXin Li #ifdef DISABLE_DEFAULT_NONFRAGILEABI_TWO
6113*67e74705SXin Li       unsigned nonFragileABIVersion = 1;
6114*67e74705SXin Li #else
6115*67e74705SXin Li       unsigned nonFragileABIVersion = 2;
6116*67e74705SXin Li #endif
6117*67e74705SXin Li 
6118*67e74705SXin Li       if (Arg *abiArg =
6119*67e74705SXin Li               args.getLastArg(options::OPT_fobjc_nonfragile_abi_version_EQ)) {
6120*67e74705SXin Li         StringRef value = abiArg->getValue();
6121*67e74705SXin Li         if (value == "1")
6122*67e74705SXin Li           nonFragileABIVersion = 1;
6123*67e74705SXin Li         else if (value == "2")
6124*67e74705SXin Li           nonFragileABIVersion = 2;
6125*67e74705SXin Li         else
6126*67e74705SXin Li           getToolChain().getDriver().Diag(diag::err_drv_clang_unsupported)
6127*67e74705SXin Li               << value;
6128*67e74705SXin Li       }
6129*67e74705SXin Li 
6130*67e74705SXin Li       objcABIVersion = 1 + nonFragileABIVersion;
6131*67e74705SXin Li     } else {
6132*67e74705SXin Li       objcABIVersion = 1;
6133*67e74705SXin Li     }
6134*67e74705SXin Li   }
6135*67e74705SXin Li 
6136*67e74705SXin Li   // We don't actually care about the ABI version other than whether
6137*67e74705SXin Li   // it's non-fragile.
6138*67e74705SXin Li   bool isNonFragile = objcABIVersion != 1;
6139*67e74705SXin Li 
6140*67e74705SXin Li   // If we have no runtime argument, ask the toolchain for its default runtime.
6141*67e74705SXin Li   // However, the rewriter only really supports the Mac runtime, so assume that.
6142*67e74705SXin Li   ObjCRuntime runtime;
6143*67e74705SXin Li   if (!runtimeArg) {
6144*67e74705SXin Li     switch (rewriteKind) {
6145*67e74705SXin Li     case RK_None:
6146*67e74705SXin Li       runtime = getToolChain().getDefaultObjCRuntime(isNonFragile);
6147*67e74705SXin Li       break;
6148*67e74705SXin Li     case RK_Fragile:
6149*67e74705SXin Li       runtime = ObjCRuntime(ObjCRuntime::FragileMacOSX, VersionTuple());
6150*67e74705SXin Li       break;
6151*67e74705SXin Li     case RK_NonFragile:
6152*67e74705SXin Li       runtime = ObjCRuntime(ObjCRuntime::MacOSX, VersionTuple());
6153*67e74705SXin Li       break;
6154*67e74705SXin Li     }
6155*67e74705SXin Li 
6156*67e74705SXin Li     // -fnext-runtime
6157*67e74705SXin Li   } else if (runtimeArg->getOption().matches(options::OPT_fnext_runtime)) {
6158*67e74705SXin Li     // On Darwin, make this use the default behavior for the toolchain.
6159*67e74705SXin Li     if (getToolChain().getTriple().isOSDarwin()) {
6160*67e74705SXin Li       runtime = getToolChain().getDefaultObjCRuntime(isNonFragile);
6161*67e74705SXin Li 
6162*67e74705SXin Li       // Otherwise, build for a generic macosx port.
6163*67e74705SXin Li     } else {
6164*67e74705SXin Li       runtime = ObjCRuntime(ObjCRuntime::MacOSX, VersionTuple());
6165*67e74705SXin Li     }
6166*67e74705SXin Li 
6167*67e74705SXin Li     // -fgnu-runtime
6168*67e74705SXin Li   } else {
6169*67e74705SXin Li     assert(runtimeArg->getOption().matches(options::OPT_fgnu_runtime));
6170*67e74705SXin Li     // Legacy behaviour is to target the gnustep runtime if we are in
6171*67e74705SXin Li     // non-fragile mode or the GCC runtime in fragile mode.
6172*67e74705SXin Li     if (isNonFragile)
6173*67e74705SXin Li       runtime = ObjCRuntime(ObjCRuntime::GNUstep, VersionTuple(1, 6));
6174*67e74705SXin Li     else
6175*67e74705SXin Li       runtime = ObjCRuntime(ObjCRuntime::GCC, VersionTuple());
6176*67e74705SXin Li   }
6177*67e74705SXin Li 
6178*67e74705SXin Li   cmdArgs.push_back(
6179*67e74705SXin Li       args.MakeArgString("-fobjc-runtime=" + runtime.getAsString()));
6180*67e74705SXin Li   return runtime;
6181*67e74705SXin Li }
6182*67e74705SXin Li 
maybeConsumeDash(const std::string & EH,size_t & I)6183*67e74705SXin Li static bool maybeConsumeDash(const std::string &EH, size_t &I) {
6184*67e74705SXin Li   bool HaveDash = (I + 1 < EH.size() && EH[I + 1] == '-');
6185*67e74705SXin Li   I += HaveDash;
6186*67e74705SXin Li   return !HaveDash;
6187*67e74705SXin Li }
6188*67e74705SXin Li 
6189*67e74705SXin Li namespace {
6190*67e74705SXin Li struct EHFlags {
6191*67e74705SXin Li   bool Synch = false;
6192*67e74705SXin Li   bool Asynch = false;
6193*67e74705SXin Li   bool NoUnwindC = false;
6194*67e74705SXin Li };
6195*67e74705SXin Li } // end anonymous namespace
6196*67e74705SXin Li 
6197*67e74705SXin Li /// /EH controls whether to run destructor cleanups when exceptions are
6198*67e74705SXin Li /// thrown.  There are three modifiers:
6199*67e74705SXin Li /// - s: Cleanup after "synchronous" exceptions, aka C++ exceptions.
6200*67e74705SXin Li /// - a: Cleanup after "asynchronous" exceptions, aka structured exceptions.
6201*67e74705SXin Li ///      The 'a' modifier is unimplemented and fundamentally hard in LLVM IR.
6202*67e74705SXin Li /// - c: Assume that extern "C" functions are implicitly nounwind.
6203*67e74705SXin Li /// The default is /EHs-c-, meaning cleanups are disabled.
parseClangCLEHFlags(const Driver & D,const ArgList & Args)6204*67e74705SXin Li static EHFlags parseClangCLEHFlags(const Driver &D, const ArgList &Args) {
6205*67e74705SXin Li   EHFlags EH;
6206*67e74705SXin Li 
6207*67e74705SXin Li   std::vector<std::string> EHArgs =
6208*67e74705SXin Li       Args.getAllArgValues(options::OPT__SLASH_EH);
6209*67e74705SXin Li   for (auto EHVal : EHArgs) {
6210*67e74705SXin Li     for (size_t I = 0, E = EHVal.size(); I != E; ++I) {
6211*67e74705SXin Li       switch (EHVal[I]) {
6212*67e74705SXin Li       case 'a':
6213*67e74705SXin Li         EH.Asynch = maybeConsumeDash(EHVal, I);
6214*67e74705SXin Li         if (EH.Asynch)
6215*67e74705SXin Li           EH.Synch = false;
6216*67e74705SXin Li         continue;
6217*67e74705SXin Li       case 'c':
6218*67e74705SXin Li         EH.NoUnwindC = maybeConsumeDash(EHVal, I);
6219*67e74705SXin Li         continue;
6220*67e74705SXin Li       case 's':
6221*67e74705SXin Li         EH.Synch = maybeConsumeDash(EHVal, I);
6222*67e74705SXin Li         if (EH.Synch)
6223*67e74705SXin Li           EH.Asynch = false;
6224*67e74705SXin Li         continue;
6225*67e74705SXin Li       default:
6226*67e74705SXin Li         break;
6227*67e74705SXin Li       }
6228*67e74705SXin Li       D.Diag(clang::diag::err_drv_invalid_value) << "/EH" << EHVal;
6229*67e74705SXin Li       break;
6230*67e74705SXin Li     }
6231*67e74705SXin Li   }
6232*67e74705SXin Li   // The /GX, /GX- flags are only processed if there are not /EH flags.
6233*67e74705SXin Li   // The default is that /GX is not specified.
6234*67e74705SXin Li   if (EHArgs.empty() &&
6235*67e74705SXin Li       Args.hasFlag(options::OPT__SLASH_GX, options::OPT__SLASH_GX_,
6236*67e74705SXin Li                    /*default=*/false)) {
6237*67e74705SXin Li     EH.Synch = true;
6238*67e74705SXin Li     EH.NoUnwindC = true;
6239*67e74705SXin Li   }
6240*67e74705SXin Li 
6241*67e74705SXin Li   return EH;
6242*67e74705SXin Li }
6243*67e74705SXin Li 
AddClangCLArgs(const ArgList & Args,types::ID InputType,ArgStringList & CmdArgs,codegenoptions::DebugInfoKind * DebugInfoKind,bool * EmitCodeView) const6244*67e74705SXin Li void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType,
6245*67e74705SXin Li                            ArgStringList &CmdArgs,
6246*67e74705SXin Li                            codegenoptions::DebugInfoKind *DebugInfoKind,
6247*67e74705SXin Li                            bool *EmitCodeView) const {
6248*67e74705SXin Li   unsigned RTOptionID = options::OPT__SLASH_MT;
6249*67e74705SXin Li 
6250*67e74705SXin Li   if (Args.hasArg(options::OPT__SLASH_LDd))
6251*67e74705SXin Li     // The /LDd option implies /MTd. The dependent lib part can be overridden,
6252*67e74705SXin Li     // but defining _DEBUG is sticky.
6253*67e74705SXin Li     RTOptionID = options::OPT__SLASH_MTd;
6254*67e74705SXin Li 
6255*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT__SLASH_M_Group))
6256*67e74705SXin Li     RTOptionID = A->getOption().getID();
6257*67e74705SXin Li 
6258*67e74705SXin Li   StringRef FlagForCRT;
6259*67e74705SXin Li   switch (RTOptionID) {
6260*67e74705SXin Li   case options::OPT__SLASH_MD:
6261*67e74705SXin Li     if (Args.hasArg(options::OPT__SLASH_LDd))
6262*67e74705SXin Li       CmdArgs.push_back("-D_DEBUG");
6263*67e74705SXin Li     CmdArgs.push_back("-D_MT");
6264*67e74705SXin Li     CmdArgs.push_back("-D_DLL");
6265*67e74705SXin Li     FlagForCRT = "--dependent-lib=msvcrt";
6266*67e74705SXin Li     break;
6267*67e74705SXin Li   case options::OPT__SLASH_MDd:
6268*67e74705SXin Li     CmdArgs.push_back("-D_DEBUG");
6269*67e74705SXin Li     CmdArgs.push_back("-D_MT");
6270*67e74705SXin Li     CmdArgs.push_back("-D_DLL");
6271*67e74705SXin Li     FlagForCRT = "--dependent-lib=msvcrtd";
6272*67e74705SXin Li     break;
6273*67e74705SXin Li   case options::OPT__SLASH_MT:
6274*67e74705SXin Li     if (Args.hasArg(options::OPT__SLASH_LDd))
6275*67e74705SXin Li       CmdArgs.push_back("-D_DEBUG");
6276*67e74705SXin Li     CmdArgs.push_back("-D_MT");
6277*67e74705SXin Li     CmdArgs.push_back("-flto-visibility-public-std");
6278*67e74705SXin Li     FlagForCRT = "--dependent-lib=libcmt";
6279*67e74705SXin Li     break;
6280*67e74705SXin Li   case options::OPT__SLASH_MTd:
6281*67e74705SXin Li     CmdArgs.push_back("-D_DEBUG");
6282*67e74705SXin Li     CmdArgs.push_back("-D_MT");
6283*67e74705SXin Li     CmdArgs.push_back("-flto-visibility-public-std");
6284*67e74705SXin Li     FlagForCRT = "--dependent-lib=libcmtd";
6285*67e74705SXin Li     break;
6286*67e74705SXin Li   default:
6287*67e74705SXin Li     llvm_unreachable("Unexpected option ID.");
6288*67e74705SXin Li   }
6289*67e74705SXin Li 
6290*67e74705SXin Li   if (Args.hasArg(options::OPT__SLASH_Zl)) {
6291*67e74705SXin Li     CmdArgs.push_back("-D_VC_NODEFAULTLIB");
6292*67e74705SXin Li   } else {
6293*67e74705SXin Li     CmdArgs.push_back(FlagForCRT.data());
6294*67e74705SXin Li 
6295*67e74705SXin Li     // This provides POSIX compatibility (maps 'open' to '_open'), which most
6296*67e74705SXin Li     // users want.  The /Za flag to cl.exe turns this off, but it's not
6297*67e74705SXin Li     // implemented in clang.
6298*67e74705SXin Li     CmdArgs.push_back("--dependent-lib=oldnames");
6299*67e74705SXin Li   }
6300*67e74705SXin Li 
6301*67e74705SXin Li   // Both /showIncludes and /E (and /EP) write to stdout. Allowing both
6302*67e74705SXin Li   // would produce interleaved output, so ignore /showIncludes in such cases.
6303*67e74705SXin Li   if (!Args.hasArg(options::OPT_E) && !Args.hasArg(options::OPT__SLASH_EP))
6304*67e74705SXin Li     if (Arg *A = Args.getLastArg(options::OPT_show_includes))
6305*67e74705SXin Li       A->render(Args, CmdArgs);
6306*67e74705SXin Li 
6307*67e74705SXin Li   // This controls whether or not we emit RTTI data for polymorphic types.
6308*67e74705SXin Li   if (Args.hasFlag(options::OPT__SLASH_GR_, options::OPT__SLASH_GR,
6309*67e74705SXin Li                    /*default=*/false))
6310*67e74705SXin Li     CmdArgs.push_back("-fno-rtti-data");
6311*67e74705SXin Li 
6312*67e74705SXin Li   // This controls whether or not we emit stack-protector instrumentation.
6313*67e74705SXin Li   // In MSVC, Buffer Security Check (/GS) is on by default.
6314*67e74705SXin Li   if (Args.hasFlag(options::OPT__SLASH_GS, options::OPT__SLASH_GS_,
6315*67e74705SXin Li                    /*default=*/true)) {
6316*67e74705SXin Li     CmdArgs.push_back("-stack-protector");
6317*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(Twine(LangOptions::SSPStrong)));
6318*67e74705SXin Li   }
6319*67e74705SXin Li 
6320*67e74705SXin Li   // Emit CodeView if -Z7 or -Zd are present.
6321*67e74705SXin Li   if (Arg *DebugInfoArg =
6322*67e74705SXin Li           Args.getLastArg(options::OPT__SLASH_Z7, options::OPT__SLASH_Zd)) {
6323*67e74705SXin Li     *EmitCodeView = true;
6324*67e74705SXin Li     if (DebugInfoArg->getOption().matches(options::OPT__SLASH_Z7))
6325*67e74705SXin Li       *DebugInfoKind = codegenoptions::LimitedDebugInfo;
6326*67e74705SXin Li     else
6327*67e74705SXin Li       *DebugInfoKind = codegenoptions::DebugLineTablesOnly;
6328*67e74705SXin Li     CmdArgs.push_back("-gcodeview");
6329*67e74705SXin Li   } else {
6330*67e74705SXin Li     *EmitCodeView = false;
6331*67e74705SXin Li   }
6332*67e74705SXin Li 
6333*67e74705SXin Li   const Driver &D = getToolChain().getDriver();
6334*67e74705SXin Li   EHFlags EH = parseClangCLEHFlags(D, Args);
6335*67e74705SXin Li   if (EH.Synch || EH.Asynch) {
6336*67e74705SXin Li     if (types::isCXX(InputType))
6337*67e74705SXin Li       CmdArgs.push_back("-fcxx-exceptions");
6338*67e74705SXin Li     CmdArgs.push_back("-fexceptions");
6339*67e74705SXin Li   }
6340*67e74705SXin Li   if (types::isCXX(InputType) && EH.Synch && EH.NoUnwindC)
6341*67e74705SXin Li     CmdArgs.push_back("-fexternc-nounwind");
6342*67e74705SXin Li 
6343*67e74705SXin Li   // /EP should expand to -E -P.
6344*67e74705SXin Li   if (Args.hasArg(options::OPT__SLASH_EP)) {
6345*67e74705SXin Li     CmdArgs.push_back("-E");
6346*67e74705SXin Li     CmdArgs.push_back("-P");
6347*67e74705SXin Li   }
6348*67e74705SXin Li 
6349*67e74705SXin Li   unsigned VolatileOptionID;
6350*67e74705SXin Li   if (getToolChain().getArch() == llvm::Triple::x86_64 ||
6351*67e74705SXin Li       getToolChain().getArch() == llvm::Triple::x86)
6352*67e74705SXin Li     VolatileOptionID = options::OPT__SLASH_volatile_ms;
6353*67e74705SXin Li   else
6354*67e74705SXin Li     VolatileOptionID = options::OPT__SLASH_volatile_iso;
6355*67e74705SXin Li 
6356*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT__SLASH_volatile_Group))
6357*67e74705SXin Li     VolatileOptionID = A->getOption().getID();
6358*67e74705SXin Li 
6359*67e74705SXin Li   if (VolatileOptionID == options::OPT__SLASH_volatile_ms)
6360*67e74705SXin Li     CmdArgs.push_back("-fms-volatile");
6361*67e74705SXin Li 
6362*67e74705SXin Li   Arg *MostGeneralArg = Args.getLastArg(options::OPT__SLASH_vmg);
6363*67e74705SXin Li   Arg *BestCaseArg = Args.getLastArg(options::OPT__SLASH_vmb);
6364*67e74705SXin Li   if (MostGeneralArg && BestCaseArg)
6365*67e74705SXin Li     D.Diag(clang::diag::err_drv_argument_not_allowed_with)
6366*67e74705SXin Li         << MostGeneralArg->getAsString(Args) << BestCaseArg->getAsString(Args);
6367*67e74705SXin Li 
6368*67e74705SXin Li   if (MostGeneralArg) {
6369*67e74705SXin Li     Arg *SingleArg = Args.getLastArg(options::OPT__SLASH_vms);
6370*67e74705SXin Li     Arg *MultipleArg = Args.getLastArg(options::OPT__SLASH_vmm);
6371*67e74705SXin Li     Arg *VirtualArg = Args.getLastArg(options::OPT__SLASH_vmv);
6372*67e74705SXin Li 
6373*67e74705SXin Li     Arg *FirstConflict = SingleArg ? SingleArg : MultipleArg;
6374*67e74705SXin Li     Arg *SecondConflict = VirtualArg ? VirtualArg : MultipleArg;
6375*67e74705SXin Li     if (FirstConflict && SecondConflict && FirstConflict != SecondConflict)
6376*67e74705SXin Li       D.Diag(clang::diag::err_drv_argument_not_allowed_with)
6377*67e74705SXin Li           << FirstConflict->getAsString(Args)
6378*67e74705SXin Li           << SecondConflict->getAsString(Args);
6379*67e74705SXin Li 
6380*67e74705SXin Li     if (SingleArg)
6381*67e74705SXin Li       CmdArgs.push_back("-fms-memptr-rep=single");
6382*67e74705SXin Li     else if (MultipleArg)
6383*67e74705SXin Li       CmdArgs.push_back("-fms-memptr-rep=multiple");
6384*67e74705SXin Li     else
6385*67e74705SXin Li       CmdArgs.push_back("-fms-memptr-rep=virtual");
6386*67e74705SXin Li   }
6387*67e74705SXin Li 
6388*67e74705SXin Li   if (Args.getLastArg(options::OPT__SLASH_Gd))
6389*67e74705SXin Li      CmdArgs.push_back("-fdefault-calling-conv=cdecl");
6390*67e74705SXin Li   else if (Args.getLastArg(options::OPT__SLASH_Gr))
6391*67e74705SXin Li      CmdArgs.push_back("-fdefault-calling-conv=fastcall");
6392*67e74705SXin Li   else if (Args.getLastArg(options::OPT__SLASH_Gz))
6393*67e74705SXin Li      CmdArgs.push_back("-fdefault-calling-conv=stdcall");
6394*67e74705SXin Li   else if (Args.getLastArg(options::OPT__SLASH_Gv))
6395*67e74705SXin Li      CmdArgs.push_back("-fdefault-calling-conv=vectorcall");
6396*67e74705SXin Li 
6397*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_vtordisp_mode_EQ))
6398*67e74705SXin Li     A->render(Args, CmdArgs);
6399*67e74705SXin Li 
6400*67e74705SXin Li   if (!Args.hasArg(options::OPT_fdiagnostics_format_EQ)) {
6401*67e74705SXin Li     CmdArgs.push_back("-fdiagnostics-format");
6402*67e74705SXin Li     if (Args.hasArg(options::OPT__SLASH_fallback))
6403*67e74705SXin Li       CmdArgs.push_back("msvc-fallback");
6404*67e74705SXin Li     else
6405*67e74705SXin Li       CmdArgs.push_back("msvc");
6406*67e74705SXin Li   }
6407*67e74705SXin Li }
6408*67e74705SXin Li 
getCLFallback() const6409*67e74705SXin Li visualstudio::Compiler *Clang::getCLFallback() const {
6410*67e74705SXin Li   if (!CLFallback)
6411*67e74705SXin Li     CLFallback.reset(new visualstudio::Compiler(getToolChain()));
6412*67e74705SXin Li   return CLFallback.get();
6413*67e74705SXin Li }
6414*67e74705SXin Li 
AddMIPSTargetArgs(const ArgList & Args,ArgStringList & CmdArgs) const6415*67e74705SXin Li void ClangAs::AddMIPSTargetArgs(const ArgList &Args,
6416*67e74705SXin Li                                 ArgStringList &CmdArgs) const {
6417*67e74705SXin Li   StringRef CPUName;
6418*67e74705SXin Li   StringRef ABIName;
6419*67e74705SXin Li   const llvm::Triple &Triple = getToolChain().getTriple();
6420*67e74705SXin Li   mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
6421*67e74705SXin Li 
6422*67e74705SXin Li   CmdArgs.push_back("-target-abi");
6423*67e74705SXin Li   CmdArgs.push_back(ABIName.data());
6424*67e74705SXin Li }
6425*67e74705SXin Li 
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const6426*67e74705SXin Li void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
6427*67e74705SXin Li                            const InputInfo &Output, const InputInfoList &Inputs,
6428*67e74705SXin Li                            const ArgList &Args,
6429*67e74705SXin Li                            const char *LinkingOutput) const {
6430*67e74705SXin Li   ArgStringList CmdArgs;
6431*67e74705SXin Li 
6432*67e74705SXin Li   assert(Inputs.size() == 1 && "Unexpected number of inputs.");
6433*67e74705SXin Li   const InputInfo &Input = Inputs[0];
6434*67e74705SXin Li 
6435*67e74705SXin Li   std::string TripleStr =
6436*67e74705SXin Li       getToolChain().ComputeEffectiveClangTriple(Args, Input.getType());
6437*67e74705SXin Li   const llvm::Triple Triple(TripleStr);
6438*67e74705SXin Li 
6439*67e74705SXin Li   // Don't warn about "clang -w -c foo.s"
6440*67e74705SXin Li   Args.ClaimAllArgs(options::OPT_w);
6441*67e74705SXin Li   // and "clang -emit-llvm -c foo.s"
6442*67e74705SXin Li   Args.ClaimAllArgs(options::OPT_emit_llvm);
6443*67e74705SXin Li 
6444*67e74705SXin Li   claimNoWarnArgs(Args);
6445*67e74705SXin Li 
6446*67e74705SXin Li   // Invoke ourselves in -cc1as mode.
6447*67e74705SXin Li   //
6448*67e74705SXin Li   // FIXME: Implement custom jobs for internal actions.
6449*67e74705SXin Li   CmdArgs.push_back("-cc1as");
6450*67e74705SXin Li 
6451*67e74705SXin Li   // Add the "effective" target triple.
6452*67e74705SXin Li   CmdArgs.push_back("-triple");
6453*67e74705SXin Li   CmdArgs.push_back(Args.MakeArgString(TripleStr));
6454*67e74705SXin Li 
6455*67e74705SXin Li   // Set the output mode, we currently only expect to be used as a real
6456*67e74705SXin Li   // assembler.
6457*67e74705SXin Li   CmdArgs.push_back("-filetype");
6458*67e74705SXin Li   CmdArgs.push_back("obj");
6459*67e74705SXin Li 
6460*67e74705SXin Li   // Set the main file name, so that debug info works even with
6461*67e74705SXin Li   // -save-temps or preprocessed assembly.
6462*67e74705SXin Li   CmdArgs.push_back("-main-file-name");
6463*67e74705SXin Li   CmdArgs.push_back(Clang::getBaseInputName(Args, Input));
6464*67e74705SXin Li 
6465*67e74705SXin Li   // Add the target cpu
6466*67e74705SXin Li   std::string CPU = getCPUName(Args, Triple, /*FromAs*/ true);
6467*67e74705SXin Li   if (!CPU.empty()) {
6468*67e74705SXin Li     CmdArgs.push_back("-target-cpu");
6469*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(CPU));
6470*67e74705SXin Li   }
6471*67e74705SXin Li 
6472*67e74705SXin Li   // Add the target features
6473*67e74705SXin Li   getTargetFeatures(getToolChain(), Triple, Args, CmdArgs, true);
6474*67e74705SXin Li 
6475*67e74705SXin Li   // Ignore explicit -force_cpusubtype_ALL option.
6476*67e74705SXin Li   (void)Args.hasArg(options::OPT_force__cpusubtype__ALL);
6477*67e74705SXin Li 
6478*67e74705SXin Li   // Pass along any -I options so we get proper .include search paths.
6479*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_I_Group);
6480*67e74705SXin Li 
6481*67e74705SXin Li   // Determine the original source input.
6482*67e74705SXin Li   const Action *SourceAction = &JA;
6483*67e74705SXin Li   while (SourceAction->getKind() != Action::InputClass) {
6484*67e74705SXin Li     assert(!SourceAction->getInputs().empty() && "unexpected root action!");
6485*67e74705SXin Li     SourceAction = SourceAction->getInputs()[0];
6486*67e74705SXin Li   }
6487*67e74705SXin Li 
6488*67e74705SXin Li   // Forward -g and handle debug info related flags, assuming we are dealing
6489*67e74705SXin Li   // with an actual assembly file.
6490*67e74705SXin Li   bool WantDebug = false;
6491*67e74705SXin Li   unsigned DwarfVersion = 0;
6492*67e74705SXin Li   Args.ClaimAllArgs(options::OPT_g_Group);
6493*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_g_Group)) {
6494*67e74705SXin Li     WantDebug = !A->getOption().matches(options::OPT_g0) &&
6495*67e74705SXin Li                 !A->getOption().matches(options::OPT_ggdb0);
6496*67e74705SXin Li     if (WantDebug)
6497*67e74705SXin Li       DwarfVersion = DwarfVersionNum(A->getSpelling());
6498*67e74705SXin Li   }
6499*67e74705SXin Li   if (DwarfVersion == 0)
6500*67e74705SXin Li     DwarfVersion = getToolChain().GetDefaultDwarfVersion();
6501*67e74705SXin Li 
6502*67e74705SXin Li   codegenoptions::DebugInfoKind DebugInfoKind = codegenoptions::NoDebugInfo;
6503*67e74705SXin Li 
6504*67e74705SXin Li   if (SourceAction->getType() == types::TY_Asm ||
6505*67e74705SXin Li       SourceAction->getType() == types::TY_PP_Asm) {
6506*67e74705SXin Li     // You might think that it would be ok to set DebugInfoKind outside of
6507*67e74705SXin Li     // the guard for source type, however there is a test which asserts
6508*67e74705SXin Li     // that some assembler invocation receives no -debug-info-kind,
6509*67e74705SXin Li     // and it's not clear whether that test is just overly restrictive.
6510*67e74705SXin Li     DebugInfoKind = (WantDebug ? codegenoptions::LimitedDebugInfo
6511*67e74705SXin Li                                : codegenoptions::NoDebugInfo);
6512*67e74705SXin Li     // Add the -fdebug-compilation-dir flag if needed.
6513*67e74705SXin Li     addDebugCompDirArg(Args, CmdArgs);
6514*67e74705SXin Li 
6515*67e74705SXin Li     // Set the AT_producer to the clang version when using the integrated
6516*67e74705SXin Li     // assembler on assembly source files.
6517*67e74705SXin Li     CmdArgs.push_back("-dwarf-debug-producer");
6518*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(getClangFullVersion()));
6519*67e74705SXin Li 
6520*67e74705SXin Li     // And pass along -I options
6521*67e74705SXin Li     Args.AddAllArgs(CmdArgs, options::OPT_I);
6522*67e74705SXin Li   }
6523*67e74705SXin Li   RenderDebugEnablingArgs(Args, CmdArgs, DebugInfoKind, DwarfVersion,
6524*67e74705SXin Li                           llvm::DebuggerKind::Default);
6525*67e74705SXin Li 
6526*67e74705SXin Li   // Handle -fPIC et al -- the relocation-model affects the assembler
6527*67e74705SXin Li   // for some targets.
6528*67e74705SXin Li   llvm::Reloc::Model RelocationModel;
6529*67e74705SXin Li   unsigned PICLevel;
6530*67e74705SXin Li   bool IsPIE;
6531*67e74705SXin Li   std::tie(RelocationModel, PICLevel, IsPIE) =
6532*67e74705SXin Li       ParsePICArgs(getToolChain(), Triple, Args);
6533*67e74705SXin Li 
6534*67e74705SXin Li   const char *RMName = RelocationModelName(RelocationModel);
6535*67e74705SXin Li   if (RMName) {
6536*67e74705SXin Li     CmdArgs.push_back("-mrelocation-model");
6537*67e74705SXin Li     CmdArgs.push_back(RMName);
6538*67e74705SXin Li   }
6539*67e74705SXin Li 
6540*67e74705SXin Li   // Optionally embed the -cc1as level arguments into the debug info, for build
6541*67e74705SXin Li   // analysis.
6542*67e74705SXin Li   if (getToolChain().UseDwarfDebugFlags()) {
6543*67e74705SXin Li     ArgStringList OriginalArgs;
6544*67e74705SXin Li     for (const auto &Arg : Args)
6545*67e74705SXin Li       Arg->render(Args, OriginalArgs);
6546*67e74705SXin Li 
6547*67e74705SXin Li     SmallString<256> Flags;
6548*67e74705SXin Li     const char *Exec = getToolChain().getDriver().getClangProgramPath();
6549*67e74705SXin Li     Flags += Exec;
6550*67e74705SXin Li     for (const char *OriginalArg : OriginalArgs) {
6551*67e74705SXin Li       SmallString<128> EscapedArg;
6552*67e74705SXin Li       EscapeSpacesAndBackslashes(OriginalArg, EscapedArg);
6553*67e74705SXin Li       Flags += " ";
6554*67e74705SXin Li       Flags += EscapedArg;
6555*67e74705SXin Li     }
6556*67e74705SXin Li     CmdArgs.push_back("-dwarf-debug-flags");
6557*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(Flags));
6558*67e74705SXin Li   }
6559*67e74705SXin Li 
6560*67e74705SXin Li   // FIXME: Add -static support, once we have it.
6561*67e74705SXin Li 
6562*67e74705SXin Li   // Add target specific flags.
6563*67e74705SXin Li   switch (getToolChain().getArch()) {
6564*67e74705SXin Li   default:
6565*67e74705SXin Li     break;
6566*67e74705SXin Li 
6567*67e74705SXin Li   case llvm::Triple::mips:
6568*67e74705SXin Li   case llvm::Triple::mipsel:
6569*67e74705SXin Li   case llvm::Triple::mips64:
6570*67e74705SXin Li   case llvm::Triple::mips64el:
6571*67e74705SXin Li     AddMIPSTargetArgs(Args, CmdArgs);
6572*67e74705SXin Li     break;
6573*67e74705SXin Li   }
6574*67e74705SXin Li 
6575*67e74705SXin Li   // Consume all the warning flags. Usually this would be handled more
6576*67e74705SXin Li   // gracefully by -cc1 (warning about unknown warning flags, etc) but -cc1as
6577*67e74705SXin Li   // doesn't handle that so rather than warning about unused flags that are
6578*67e74705SXin Li   // actually used, we'll lie by omission instead.
6579*67e74705SXin Li   // FIXME: Stop lying and consume only the appropriate driver flags
6580*67e74705SXin Li   Args.ClaimAllArgs(options::OPT_W_Group);
6581*67e74705SXin Li 
6582*67e74705SXin Li   CollectArgsForIntegratedAssembler(C, Args, CmdArgs,
6583*67e74705SXin Li                                     getToolChain().getDriver());
6584*67e74705SXin Li 
6585*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_mllvm);
6586*67e74705SXin Li 
6587*67e74705SXin Li   assert(Output.isFilename() && "Unexpected lipo output.");
6588*67e74705SXin Li   CmdArgs.push_back("-o");
6589*67e74705SXin Li   CmdArgs.push_back(Output.getFilename());
6590*67e74705SXin Li 
6591*67e74705SXin Li   assert(Input.isFilename() && "Invalid input.");
6592*67e74705SXin Li   CmdArgs.push_back(Input.getFilename());
6593*67e74705SXin Li 
6594*67e74705SXin Li   const char *Exec = getToolChain().getDriver().getClangProgramPath();
6595*67e74705SXin Li   C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
6596*67e74705SXin Li 
6597*67e74705SXin Li   // Handle the debug info splitting at object creation time if we're
6598*67e74705SXin Li   // creating an object.
6599*67e74705SXin Li   // TODO: Currently only works on linux with newer objcopy.
6600*67e74705SXin Li   if (Args.hasArg(options::OPT_gsplit_dwarf) &&
6601*67e74705SXin Li       getToolChain().getTriple().isOSLinux())
6602*67e74705SXin Li     SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output,
6603*67e74705SXin Li                    SplitDebugName(Args, Input));
6604*67e74705SXin Li }
6605*67e74705SXin Li 
anchor()6606*67e74705SXin Li void GnuTool::anchor() {}
6607*67e74705SXin Li 
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const6608*67e74705SXin Li void gcc::Common::ConstructJob(Compilation &C, const JobAction &JA,
6609*67e74705SXin Li                                const InputInfo &Output,
6610*67e74705SXin Li                                const InputInfoList &Inputs, const ArgList &Args,
6611*67e74705SXin Li                                const char *LinkingOutput) const {
6612*67e74705SXin Li   const Driver &D = getToolChain().getDriver();
6613*67e74705SXin Li   ArgStringList CmdArgs;
6614*67e74705SXin Li 
6615*67e74705SXin Li   for (const auto &A : Args) {
6616*67e74705SXin Li     if (forwardToGCC(A->getOption())) {
6617*67e74705SXin Li       // It is unfortunate that we have to claim here, as this means
6618*67e74705SXin Li       // we will basically never report anything interesting for
6619*67e74705SXin Li       // platforms using a generic gcc, even if we are just using gcc
6620*67e74705SXin Li       // to get to the assembler.
6621*67e74705SXin Li       A->claim();
6622*67e74705SXin Li 
6623*67e74705SXin Li       // Don't forward any -g arguments to assembly steps.
6624*67e74705SXin Li       if (isa<AssembleJobAction>(JA) &&
6625*67e74705SXin Li           A->getOption().matches(options::OPT_g_Group))
6626*67e74705SXin Li         continue;
6627*67e74705SXin Li 
6628*67e74705SXin Li       // Don't forward any -W arguments to assembly and link steps.
6629*67e74705SXin Li       if ((isa<AssembleJobAction>(JA) || isa<LinkJobAction>(JA)) &&
6630*67e74705SXin Li           A->getOption().matches(options::OPT_W_Group))
6631*67e74705SXin Li         continue;
6632*67e74705SXin Li 
6633*67e74705SXin Li       A->render(Args, CmdArgs);
6634*67e74705SXin Li     }
6635*67e74705SXin Li   }
6636*67e74705SXin Li 
6637*67e74705SXin Li   RenderExtraToolArgs(JA, CmdArgs);
6638*67e74705SXin Li 
6639*67e74705SXin Li   // If using a driver driver, force the arch.
6640*67e74705SXin Li   if (getToolChain().getTriple().isOSDarwin()) {
6641*67e74705SXin Li     CmdArgs.push_back("-arch");
6642*67e74705SXin Li     CmdArgs.push_back(
6643*67e74705SXin Li         Args.MakeArgString(getToolChain().getDefaultUniversalArchName()));
6644*67e74705SXin Li   }
6645*67e74705SXin Li 
6646*67e74705SXin Li   // Try to force gcc to match the tool chain we want, if we recognize
6647*67e74705SXin Li   // the arch.
6648*67e74705SXin Li   //
6649*67e74705SXin Li   // FIXME: The triple class should directly provide the information we want
6650*67e74705SXin Li   // here.
6651*67e74705SXin Li   switch (getToolChain().getArch()) {
6652*67e74705SXin Li   default:
6653*67e74705SXin Li     break;
6654*67e74705SXin Li   case llvm::Triple::x86:
6655*67e74705SXin Li   case llvm::Triple::ppc:
6656*67e74705SXin Li     CmdArgs.push_back("-m32");
6657*67e74705SXin Li     break;
6658*67e74705SXin Li   case llvm::Triple::x86_64:
6659*67e74705SXin Li   case llvm::Triple::ppc64:
6660*67e74705SXin Li   case llvm::Triple::ppc64le:
6661*67e74705SXin Li     CmdArgs.push_back("-m64");
6662*67e74705SXin Li     break;
6663*67e74705SXin Li   case llvm::Triple::sparcel:
6664*67e74705SXin Li     CmdArgs.push_back("-EL");
6665*67e74705SXin Li     break;
6666*67e74705SXin Li   }
6667*67e74705SXin Li 
6668*67e74705SXin Li   if (Output.isFilename()) {
6669*67e74705SXin Li     CmdArgs.push_back("-o");
6670*67e74705SXin Li     CmdArgs.push_back(Output.getFilename());
6671*67e74705SXin Li   } else {
6672*67e74705SXin Li     assert(Output.isNothing() && "Unexpected output");
6673*67e74705SXin Li     CmdArgs.push_back("-fsyntax-only");
6674*67e74705SXin Li   }
6675*67e74705SXin Li 
6676*67e74705SXin Li   Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
6677*67e74705SXin Li 
6678*67e74705SXin Li   // Only pass -x if gcc will understand it; otherwise hope gcc
6679*67e74705SXin Li   // understands the suffix correctly. The main use case this would go
6680*67e74705SXin Li   // wrong in is for linker inputs if they happened to have an odd
6681*67e74705SXin Li   // suffix; really the only way to get this to happen is a command
6682*67e74705SXin Li   // like '-x foobar a.c' which will treat a.c like a linker input.
6683*67e74705SXin Li   //
6684*67e74705SXin Li   // FIXME: For the linker case specifically, can we safely convert
6685*67e74705SXin Li   // inputs into '-Wl,' options?
6686*67e74705SXin Li   for (const auto &II : Inputs) {
6687*67e74705SXin Li     // Don't try to pass LLVM or AST inputs to a generic gcc.
6688*67e74705SXin Li     if (types::isLLVMIR(II.getType()))
6689*67e74705SXin Li       D.Diag(diag::err_drv_no_linker_llvm_support)
6690*67e74705SXin Li           << getToolChain().getTripleString();
6691*67e74705SXin Li     else if (II.getType() == types::TY_AST)
6692*67e74705SXin Li       D.Diag(diag::err_drv_no_ast_support) << getToolChain().getTripleString();
6693*67e74705SXin Li     else if (II.getType() == types::TY_ModuleFile)
6694*67e74705SXin Li       D.Diag(diag::err_drv_no_module_support)
6695*67e74705SXin Li           << getToolChain().getTripleString();
6696*67e74705SXin Li 
6697*67e74705SXin Li     if (types::canTypeBeUserSpecified(II.getType())) {
6698*67e74705SXin Li       CmdArgs.push_back("-x");
6699*67e74705SXin Li       CmdArgs.push_back(types::getTypeName(II.getType()));
6700*67e74705SXin Li     }
6701*67e74705SXin Li 
6702*67e74705SXin Li     if (II.isFilename())
6703*67e74705SXin Li       CmdArgs.push_back(II.getFilename());
6704*67e74705SXin Li     else {
6705*67e74705SXin Li       const Arg &A = II.getInputArg();
6706*67e74705SXin Li 
6707*67e74705SXin Li       // Reverse translate some rewritten options.
6708*67e74705SXin Li       if (A.getOption().matches(options::OPT_Z_reserved_lib_stdcxx)) {
6709*67e74705SXin Li         CmdArgs.push_back("-lstdc++");
6710*67e74705SXin Li         continue;
6711*67e74705SXin Li       }
6712*67e74705SXin Li 
6713*67e74705SXin Li       // Don't render as input, we need gcc to do the translations.
6714*67e74705SXin Li       A.render(Args, CmdArgs);
6715*67e74705SXin Li     }
6716*67e74705SXin Li   }
6717*67e74705SXin Li 
6718*67e74705SXin Li   const std::string &customGCCName = D.getCCCGenericGCCName();
6719*67e74705SXin Li   const char *GCCName;
6720*67e74705SXin Li   if (!customGCCName.empty())
6721*67e74705SXin Li     GCCName = customGCCName.c_str();
6722*67e74705SXin Li   else if (D.CCCIsCXX()) {
6723*67e74705SXin Li     GCCName = "g++";
6724*67e74705SXin Li   } else
6725*67e74705SXin Li     GCCName = "gcc";
6726*67e74705SXin Li 
6727*67e74705SXin Li   const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath(GCCName));
6728*67e74705SXin Li   C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
6729*67e74705SXin Li }
6730*67e74705SXin Li 
RenderExtraToolArgs(const JobAction & JA,ArgStringList & CmdArgs) const6731*67e74705SXin Li void gcc::Preprocessor::RenderExtraToolArgs(const JobAction &JA,
6732*67e74705SXin Li                                             ArgStringList &CmdArgs) const {
6733*67e74705SXin Li   CmdArgs.push_back("-E");
6734*67e74705SXin Li }
6735*67e74705SXin Li 
RenderExtraToolArgs(const JobAction & JA,ArgStringList & CmdArgs) const6736*67e74705SXin Li void gcc::Compiler::RenderExtraToolArgs(const JobAction &JA,
6737*67e74705SXin Li                                         ArgStringList &CmdArgs) const {
6738*67e74705SXin Li   const Driver &D = getToolChain().getDriver();
6739*67e74705SXin Li 
6740*67e74705SXin Li   switch (JA.getType()) {
6741*67e74705SXin Li   // If -flto, etc. are present then make sure not to force assembly output.
6742*67e74705SXin Li   case types::TY_LLVM_IR:
6743*67e74705SXin Li   case types::TY_LTO_IR:
6744*67e74705SXin Li   case types::TY_LLVM_BC:
6745*67e74705SXin Li   case types::TY_LTO_BC:
6746*67e74705SXin Li     CmdArgs.push_back("-c");
6747*67e74705SXin Li     break;
6748*67e74705SXin Li   // We assume we've got an "integrated" assembler in that gcc will produce an
6749*67e74705SXin Li   // object file itself.
6750*67e74705SXin Li   case types::TY_Object:
6751*67e74705SXin Li     CmdArgs.push_back("-c");
6752*67e74705SXin Li     break;
6753*67e74705SXin Li   case types::TY_PP_Asm:
6754*67e74705SXin Li     CmdArgs.push_back("-S");
6755*67e74705SXin Li     break;
6756*67e74705SXin Li   case types::TY_Nothing:
6757*67e74705SXin Li     CmdArgs.push_back("-fsyntax-only");
6758*67e74705SXin Li     break;
6759*67e74705SXin Li   default:
6760*67e74705SXin Li     D.Diag(diag::err_drv_invalid_gcc_output_type) << getTypeName(JA.getType());
6761*67e74705SXin Li   }
6762*67e74705SXin Li }
6763*67e74705SXin Li 
RenderExtraToolArgs(const JobAction & JA,ArgStringList & CmdArgs) const6764*67e74705SXin Li void gcc::Linker::RenderExtraToolArgs(const JobAction &JA,
6765*67e74705SXin Li                                       ArgStringList &CmdArgs) const {
6766*67e74705SXin Li   // The types are (hopefully) good enough.
6767*67e74705SXin Li }
6768*67e74705SXin Li 
6769*67e74705SXin Li // Hexagon tools start.
RenderExtraToolArgs(const JobAction & JA,ArgStringList & CmdArgs) const6770*67e74705SXin Li void hexagon::Assembler::RenderExtraToolArgs(const JobAction &JA,
6771*67e74705SXin Li                                              ArgStringList &CmdArgs) const {
6772*67e74705SXin Li }
6773*67e74705SXin Li 
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const6774*67e74705SXin Li void hexagon::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
6775*67e74705SXin Li                                       const InputInfo &Output,
6776*67e74705SXin Li                                       const InputInfoList &Inputs,
6777*67e74705SXin Li                                       const ArgList &Args,
6778*67e74705SXin Li                                       const char *LinkingOutput) const {
6779*67e74705SXin Li   claimNoWarnArgs(Args);
6780*67e74705SXin Li 
6781*67e74705SXin Li   auto &HTC = static_cast<const toolchains::HexagonToolChain&>(getToolChain());
6782*67e74705SXin Li   const Driver &D = HTC.getDriver();
6783*67e74705SXin Li   ArgStringList CmdArgs;
6784*67e74705SXin Li 
6785*67e74705SXin Li   std::string MArchString = "-march=hexagon";
6786*67e74705SXin Li   CmdArgs.push_back(Args.MakeArgString(MArchString));
6787*67e74705SXin Li 
6788*67e74705SXin Li   RenderExtraToolArgs(JA, CmdArgs);
6789*67e74705SXin Li 
6790*67e74705SXin Li   std::string AsName = "hexagon-llvm-mc";
6791*67e74705SXin Li   std::string MCpuString = "-mcpu=hexagon" +
6792*67e74705SXin Li         toolchains::HexagonToolChain::GetTargetCPUVersion(Args).str();
6793*67e74705SXin Li   CmdArgs.push_back("-filetype=obj");
6794*67e74705SXin Li   CmdArgs.push_back(Args.MakeArgString(MCpuString));
6795*67e74705SXin Li 
6796*67e74705SXin Li   if (Output.isFilename()) {
6797*67e74705SXin Li     CmdArgs.push_back("-o");
6798*67e74705SXin Li     CmdArgs.push_back(Output.getFilename());
6799*67e74705SXin Li   } else {
6800*67e74705SXin Li     assert(Output.isNothing() && "Unexpected output");
6801*67e74705SXin Li     CmdArgs.push_back("-fsyntax-only");
6802*67e74705SXin Li   }
6803*67e74705SXin Li 
6804*67e74705SXin Li   if (auto G = toolchains::HexagonToolChain::getSmallDataThreshold(Args)) {
6805*67e74705SXin Li     std::string N = llvm::utostr(G.getValue());
6806*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(std::string("-gpsize=") + N));
6807*67e74705SXin Li   }
6808*67e74705SXin Li 
6809*67e74705SXin Li   Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
6810*67e74705SXin Li 
6811*67e74705SXin Li   // Only pass -x if gcc will understand it; otherwise hope gcc
6812*67e74705SXin Li   // understands the suffix correctly. The main use case this would go
6813*67e74705SXin Li   // wrong in is for linker inputs if they happened to have an odd
6814*67e74705SXin Li   // suffix; really the only way to get this to happen is a command
6815*67e74705SXin Li   // like '-x foobar a.c' which will treat a.c like a linker input.
6816*67e74705SXin Li   //
6817*67e74705SXin Li   // FIXME: For the linker case specifically, can we safely convert
6818*67e74705SXin Li   // inputs into '-Wl,' options?
6819*67e74705SXin Li   for (const auto &II : Inputs) {
6820*67e74705SXin Li     // Don't try to pass LLVM or AST inputs to a generic gcc.
6821*67e74705SXin Li     if (types::isLLVMIR(II.getType()))
6822*67e74705SXin Li       D.Diag(clang::diag::err_drv_no_linker_llvm_support)
6823*67e74705SXin Li           << HTC.getTripleString();
6824*67e74705SXin Li     else if (II.getType() == types::TY_AST)
6825*67e74705SXin Li       D.Diag(clang::diag::err_drv_no_ast_support)
6826*67e74705SXin Li           << HTC.getTripleString();
6827*67e74705SXin Li     else if (II.getType() == types::TY_ModuleFile)
6828*67e74705SXin Li       D.Diag(diag::err_drv_no_module_support)
6829*67e74705SXin Li           << HTC.getTripleString();
6830*67e74705SXin Li 
6831*67e74705SXin Li     if (II.isFilename())
6832*67e74705SXin Li       CmdArgs.push_back(II.getFilename());
6833*67e74705SXin Li     else
6834*67e74705SXin Li       // Don't render as input, we need gcc to do the translations.
6835*67e74705SXin Li       // FIXME: What is this?
6836*67e74705SXin Li       II.getInputArg().render(Args, CmdArgs);
6837*67e74705SXin Li   }
6838*67e74705SXin Li 
6839*67e74705SXin Li   auto *Exec = Args.MakeArgString(HTC.GetProgramPath(AsName.c_str()));
6840*67e74705SXin Li   C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
6841*67e74705SXin Li }
6842*67e74705SXin Li 
RenderExtraToolArgs(const JobAction & JA,ArgStringList & CmdArgs) const6843*67e74705SXin Li void hexagon::Linker::RenderExtraToolArgs(const JobAction &JA,
6844*67e74705SXin Li                                           ArgStringList &CmdArgs) const {
6845*67e74705SXin Li }
6846*67e74705SXin Li 
6847*67e74705SXin Li static void
constructHexagonLinkArgs(Compilation & C,const JobAction & JA,const toolchains::HexagonToolChain & HTC,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,ArgStringList & CmdArgs,const char * LinkingOutput)6848*67e74705SXin Li constructHexagonLinkArgs(Compilation &C, const JobAction &JA,
6849*67e74705SXin Li                          const toolchains::HexagonToolChain &HTC,
6850*67e74705SXin Li                          const InputInfo &Output, const InputInfoList &Inputs,
6851*67e74705SXin Li                          const ArgList &Args, ArgStringList &CmdArgs,
6852*67e74705SXin Li                          const char *LinkingOutput) {
6853*67e74705SXin Li 
6854*67e74705SXin Li   const Driver &D = HTC.getDriver();
6855*67e74705SXin Li 
6856*67e74705SXin Li   //----------------------------------------------------------------------------
6857*67e74705SXin Li   //
6858*67e74705SXin Li   //----------------------------------------------------------------------------
6859*67e74705SXin Li   bool IsStatic = Args.hasArg(options::OPT_static);
6860*67e74705SXin Li   bool IsShared = Args.hasArg(options::OPT_shared);
6861*67e74705SXin Li   bool IsPIE = Args.hasArg(options::OPT_pie);
6862*67e74705SXin Li   bool IncStdLib = !Args.hasArg(options::OPT_nostdlib);
6863*67e74705SXin Li   bool IncStartFiles = !Args.hasArg(options::OPT_nostartfiles);
6864*67e74705SXin Li   bool IncDefLibs = !Args.hasArg(options::OPT_nodefaultlibs);
6865*67e74705SXin Li   bool UseG0 = false;
6866*67e74705SXin Li   bool UseShared = IsShared && !IsStatic;
6867*67e74705SXin Li 
6868*67e74705SXin Li   //----------------------------------------------------------------------------
6869*67e74705SXin Li   // Silence warnings for various options
6870*67e74705SXin Li   //----------------------------------------------------------------------------
6871*67e74705SXin Li   Args.ClaimAllArgs(options::OPT_g_Group);
6872*67e74705SXin Li   Args.ClaimAllArgs(options::OPT_emit_llvm);
6873*67e74705SXin Li   Args.ClaimAllArgs(options::OPT_w); // Other warning options are already
6874*67e74705SXin Li                                      // handled somewhere else.
6875*67e74705SXin Li   Args.ClaimAllArgs(options::OPT_static_libgcc);
6876*67e74705SXin Li 
6877*67e74705SXin Li   //----------------------------------------------------------------------------
6878*67e74705SXin Li   //
6879*67e74705SXin Li   //----------------------------------------------------------------------------
6880*67e74705SXin Li   if (Args.hasArg(options::OPT_s))
6881*67e74705SXin Li     CmdArgs.push_back("-s");
6882*67e74705SXin Li 
6883*67e74705SXin Li   if (Args.hasArg(options::OPT_r))
6884*67e74705SXin Li     CmdArgs.push_back("-r");
6885*67e74705SXin Li 
6886*67e74705SXin Li   for (const auto &Opt : HTC.ExtraOpts)
6887*67e74705SXin Li     CmdArgs.push_back(Opt.c_str());
6888*67e74705SXin Li 
6889*67e74705SXin Li   CmdArgs.push_back("-march=hexagon");
6890*67e74705SXin Li   std::string CpuVer =
6891*67e74705SXin Li         toolchains::HexagonToolChain::GetTargetCPUVersion(Args).str();
6892*67e74705SXin Li   std::string MCpuString = "-mcpu=hexagon" + CpuVer;
6893*67e74705SXin Li   CmdArgs.push_back(Args.MakeArgString(MCpuString));
6894*67e74705SXin Li 
6895*67e74705SXin Li   if (IsShared) {
6896*67e74705SXin Li     CmdArgs.push_back("-shared");
6897*67e74705SXin Li     // The following should be the default, but doing as hexagon-gcc does.
6898*67e74705SXin Li     CmdArgs.push_back("-call_shared");
6899*67e74705SXin Li   }
6900*67e74705SXin Li 
6901*67e74705SXin Li   if (IsStatic)
6902*67e74705SXin Li     CmdArgs.push_back("-static");
6903*67e74705SXin Li 
6904*67e74705SXin Li   if (IsPIE && !IsShared)
6905*67e74705SXin Li     CmdArgs.push_back("-pie");
6906*67e74705SXin Li 
6907*67e74705SXin Li   if (auto G = toolchains::HexagonToolChain::getSmallDataThreshold(Args)) {
6908*67e74705SXin Li     std::string N = llvm::utostr(G.getValue());
6909*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(std::string("-G") + N));
6910*67e74705SXin Li     UseG0 = G.getValue() == 0;
6911*67e74705SXin Li   }
6912*67e74705SXin Li 
6913*67e74705SXin Li   //----------------------------------------------------------------------------
6914*67e74705SXin Li   //
6915*67e74705SXin Li   //----------------------------------------------------------------------------
6916*67e74705SXin Li   CmdArgs.push_back("-o");
6917*67e74705SXin Li   CmdArgs.push_back(Output.getFilename());
6918*67e74705SXin Li 
6919*67e74705SXin Li   //----------------------------------------------------------------------------
6920*67e74705SXin Li   // moslib
6921*67e74705SXin Li   //----------------------------------------------------------------------------
6922*67e74705SXin Li   std::vector<std::string> OsLibs;
6923*67e74705SXin Li   bool HasStandalone = false;
6924*67e74705SXin Li 
6925*67e74705SXin Li   for (const Arg *A : Args.filtered(options::OPT_moslib_EQ)) {
6926*67e74705SXin Li     A->claim();
6927*67e74705SXin Li     OsLibs.emplace_back(A->getValue());
6928*67e74705SXin Li     HasStandalone = HasStandalone || (OsLibs.back() == "standalone");
6929*67e74705SXin Li   }
6930*67e74705SXin Li   if (OsLibs.empty()) {
6931*67e74705SXin Li     OsLibs.push_back("standalone");
6932*67e74705SXin Li     HasStandalone = true;
6933*67e74705SXin Li   }
6934*67e74705SXin Li 
6935*67e74705SXin Li   //----------------------------------------------------------------------------
6936*67e74705SXin Li   // Start Files
6937*67e74705SXin Li   //----------------------------------------------------------------------------
6938*67e74705SXin Li   const std::string MCpuSuffix = "/" + CpuVer;
6939*67e74705SXin Li   const std::string MCpuG0Suffix = MCpuSuffix + "/G0";
6940*67e74705SXin Li   const std::string RootDir =
6941*67e74705SXin Li       HTC.getHexagonTargetDir(D.InstalledDir, D.PrefixDirs) + "/";
6942*67e74705SXin Li   const std::string StartSubDir =
6943*67e74705SXin Li       "hexagon/lib" + (UseG0 ? MCpuG0Suffix : MCpuSuffix);
6944*67e74705SXin Li 
6945*67e74705SXin Li   auto Find = [&HTC] (const std::string &RootDir, const std::string &SubDir,
6946*67e74705SXin Li                       const char *Name) -> std::string {
6947*67e74705SXin Li     std::string RelName = SubDir + Name;
6948*67e74705SXin Li     std::string P = HTC.GetFilePath(RelName.c_str());
6949*67e74705SXin Li     if (llvm::sys::fs::exists(P))
6950*67e74705SXin Li       return P;
6951*67e74705SXin Li     return RootDir + RelName;
6952*67e74705SXin Li   };
6953*67e74705SXin Li 
6954*67e74705SXin Li   if (IncStdLib && IncStartFiles) {
6955*67e74705SXin Li     if (!IsShared) {
6956*67e74705SXin Li       if (HasStandalone) {
6957*67e74705SXin Li         std::string Crt0SA = Find(RootDir, StartSubDir, "/crt0_standalone.o");
6958*67e74705SXin Li         CmdArgs.push_back(Args.MakeArgString(Crt0SA));
6959*67e74705SXin Li       }
6960*67e74705SXin Li       std::string Crt0 = Find(RootDir, StartSubDir, "/crt0.o");
6961*67e74705SXin Li       CmdArgs.push_back(Args.MakeArgString(Crt0));
6962*67e74705SXin Li     }
6963*67e74705SXin Li     std::string Init = UseShared
6964*67e74705SXin Li           ? Find(RootDir, StartSubDir + "/pic", "/initS.o")
6965*67e74705SXin Li           : Find(RootDir, StartSubDir, "/init.o");
6966*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(Init));
6967*67e74705SXin Li   }
6968*67e74705SXin Li 
6969*67e74705SXin Li   //----------------------------------------------------------------------------
6970*67e74705SXin Li   // Library Search Paths
6971*67e74705SXin Li   //----------------------------------------------------------------------------
6972*67e74705SXin Li   const ToolChain::path_list &LibPaths = HTC.getFilePaths();
6973*67e74705SXin Li   for (const auto &LibPath : LibPaths)
6974*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + LibPath));
6975*67e74705SXin Li 
6976*67e74705SXin Li   //----------------------------------------------------------------------------
6977*67e74705SXin Li   //
6978*67e74705SXin Li   //----------------------------------------------------------------------------
6979*67e74705SXin Li   Args.AddAllArgs(CmdArgs,
6980*67e74705SXin Li                   {options::OPT_T_Group, options::OPT_e, options::OPT_s,
6981*67e74705SXin Li                    options::OPT_t, options::OPT_u_Group});
6982*67e74705SXin Li 
6983*67e74705SXin Li   AddLinkerInputs(HTC, Inputs, Args, CmdArgs);
6984*67e74705SXin Li 
6985*67e74705SXin Li   //----------------------------------------------------------------------------
6986*67e74705SXin Li   // Libraries
6987*67e74705SXin Li   //----------------------------------------------------------------------------
6988*67e74705SXin Li   if (IncStdLib && IncDefLibs) {
6989*67e74705SXin Li     if (D.CCCIsCXX()) {
6990*67e74705SXin Li       HTC.AddCXXStdlibLibArgs(Args, CmdArgs);
6991*67e74705SXin Li       CmdArgs.push_back("-lm");
6992*67e74705SXin Li     }
6993*67e74705SXin Li 
6994*67e74705SXin Li     CmdArgs.push_back("--start-group");
6995*67e74705SXin Li 
6996*67e74705SXin Li     if (!IsShared) {
6997*67e74705SXin Li       for (const std::string &Lib : OsLibs)
6998*67e74705SXin Li         CmdArgs.push_back(Args.MakeArgString("-l" + Lib));
6999*67e74705SXin Li       CmdArgs.push_back("-lc");
7000*67e74705SXin Li     }
7001*67e74705SXin Li     CmdArgs.push_back("-lgcc");
7002*67e74705SXin Li 
7003*67e74705SXin Li     CmdArgs.push_back("--end-group");
7004*67e74705SXin Li   }
7005*67e74705SXin Li 
7006*67e74705SXin Li   //----------------------------------------------------------------------------
7007*67e74705SXin Li   // End files
7008*67e74705SXin Li   //----------------------------------------------------------------------------
7009*67e74705SXin Li   if (IncStdLib && IncStartFiles) {
7010*67e74705SXin Li     std::string Fini = UseShared
7011*67e74705SXin Li           ? Find(RootDir, StartSubDir + "/pic", "/finiS.o")
7012*67e74705SXin Li           : Find(RootDir, StartSubDir, "/fini.o");
7013*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(Fini));
7014*67e74705SXin Li   }
7015*67e74705SXin Li }
7016*67e74705SXin Li 
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const7017*67e74705SXin Li void hexagon::Linker::ConstructJob(Compilation &C, const JobAction &JA,
7018*67e74705SXin Li                                    const InputInfo &Output,
7019*67e74705SXin Li                                    const InputInfoList &Inputs,
7020*67e74705SXin Li                                    const ArgList &Args,
7021*67e74705SXin Li                                    const char *LinkingOutput) const {
7022*67e74705SXin Li   auto &HTC = static_cast<const toolchains::HexagonToolChain&>(getToolChain());
7023*67e74705SXin Li 
7024*67e74705SXin Li   ArgStringList CmdArgs;
7025*67e74705SXin Li   constructHexagonLinkArgs(C, JA, HTC, Output, Inputs, Args, CmdArgs,
7026*67e74705SXin Li                            LinkingOutput);
7027*67e74705SXin Li 
7028*67e74705SXin Li   std::string Linker = HTC.GetProgramPath("hexagon-link");
7029*67e74705SXin Li   C.addCommand(llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Linker),
7030*67e74705SXin Li                                           CmdArgs, Inputs));
7031*67e74705SXin Li }
7032*67e74705SXin Li // Hexagon tools end.
7033*67e74705SXin Li 
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const7034*67e74705SXin Li void amdgpu::Linker::ConstructJob(Compilation &C, const JobAction &JA,
7035*67e74705SXin Li                                   const InputInfo &Output,
7036*67e74705SXin Li                                   const InputInfoList &Inputs,
7037*67e74705SXin Li                                   const ArgList &Args,
7038*67e74705SXin Li                                   const char *LinkingOutput) const {
7039*67e74705SXin Li 
7040*67e74705SXin Li   std::string Linker = getToolChain().GetProgramPath(getShortName());
7041*67e74705SXin Li   ArgStringList CmdArgs;
7042*67e74705SXin Li   AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
7043*67e74705SXin Li   CmdArgs.push_back("-shared");
7044*67e74705SXin Li   CmdArgs.push_back("-o");
7045*67e74705SXin Li   CmdArgs.push_back(Output.getFilename());
7046*67e74705SXin Li   C.addCommand(llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Linker),
7047*67e74705SXin Li                                           CmdArgs, Inputs));
7048*67e74705SXin Li }
7049*67e74705SXin Li // AMDGPU tools end.
7050*67e74705SXin Li 
Linker(const ToolChain & TC)7051*67e74705SXin Li wasm::Linker::Linker(const ToolChain &TC)
7052*67e74705SXin Li   : GnuTool("wasm::Linker", "lld", TC) {}
7053*67e74705SXin Li 
isLinkJob() const7054*67e74705SXin Li bool wasm::Linker::isLinkJob() const {
7055*67e74705SXin Li   return true;
7056*67e74705SXin Li }
7057*67e74705SXin Li 
hasIntegratedCPP() const7058*67e74705SXin Li bool wasm::Linker::hasIntegratedCPP() const {
7059*67e74705SXin Li   return false;
7060*67e74705SXin Li }
7061*67e74705SXin Li 
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const7062*67e74705SXin Li void wasm::Linker::ConstructJob(Compilation &C, const JobAction &JA,
7063*67e74705SXin Li                                 const InputInfo &Output,
7064*67e74705SXin Li                                 const InputInfoList &Inputs,
7065*67e74705SXin Li                                 const ArgList &Args,
7066*67e74705SXin Li                                 const char *LinkingOutput) const {
7067*67e74705SXin Li 
7068*67e74705SXin Li   const ToolChain &ToolChain = getToolChain();
7069*67e74705SXin Li   const Driver &D = ToolChain.getDriver();
7070*67e74705SXin Li   const char *Linker = Args.MakeArgString(ToolChain.GetLinkerPath());
7071*67e74705SXin Li   ArgStringList CmdArgs;
7072*67e74705SXin Li   CmdArgs.push_back("-flavor");
7073*67e74705SXin Li   CmdArgs.push_back("ld");
7074*67e74705SXin Li 
7075*67e74705SXin Li   // Enable garbage collection of unused input sections by default, since code
7076*67e74705SXin Li   // size is of particular importance. This is significantly facilitated by
7077*67e74705SXin Li   // the enabling of -ffunction-sections and -fdata-sections in
7078*67e74705SXin Li   // Clang::ConstructJob.
7079*67e74705SXin Li   if (areOptimizationsEnabled(Args))
7080*67e74705SXin Li     CmdArgs.push_back("--gc-sections");
7081*67e74705SXin Li 
7082*67e74705SXin Li   if (Args.hasArg(options::OPT_rdynamic))
7083*67e74705SXin Li     CmdArgs.push_back("-export-dynamic");
7084*67e74705SXin Li   if (Args.hasArg(options::OPT_s))
7085*67e74705SXin Li     CmdArgs.push_back("--strip-all");
7086*67e74705SXin Li   if (Args.hasArg(options::OPT_shared))
7087*67e74705SXin Li     CmdArgs.push_back("-shared");
7088*67e74705SXin Li   if (Args.hasArg(options::OPT_static))
7089*67e74705SXin Li     CmdArgs.push_back("-Bstatic");
7090*67e74705SXin Li 
7091*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_L);
7092*67e74705SXin Li   ToolChain.AddFilePathLibArgs(Args, CmdArgs);
7093*67e74705SXin Li 
7094*67e74705SXin Li   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
7095*67e74705SXin Li     if (Args.hasArg(options::OPT_shared))
7096*67e74705SXin Li       CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("rcrt1.o")));
7097*67e74705SXin Li     else if (Args.hasArg(options::OPT_pie))
7098*67e74705SXin Li       CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("Scrt1.o")));
7099*67e74705SXin Li     else
7100*67e74705SXin Li       CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crt1.o")));
7101*67e74705SXin Li 
7102*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o")));
7103*67e74705SXin Li   }
7104*67e74705SXin Li 
7105*67e74705SXin Li   AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
7106*67e74705SXin Li 
7107*67e74705SXin Li   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
7108*67e74705SXin Li     if (D.CCCIsCXX())
7109*67e74705SXin Li       ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
7110*67e74705SXin Li 
7111*67e74705SXin Li     if (Args.hasArg(options::OPT_pthread))
7112*67e74705SXin Li       CmdArgs.push_back("-lpthread");
7113*67e74705SXin Li 
7114*67e74705SXin Li     CmdArgs.push_back("-lc");
7115*67e74705SXin Li     CmdArgs.push_back("-lcompiler_rt");
7116*67e74705SXin Li   }
7117*67e74705SXin Li 
7118*67e74705SXin Li   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles))
7119*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o")));
7120*67e74705SXin Li 
7121*67e74705SXin Li   CmdArgs.push_back("-o");
7122*67e74705SXin Li   CmdArgs.push_back(Output.getFilename());
7123*67e74705SXin Li 
7124*67e74705SXin Li   C.addCommand(llvm::make_unique<Command>(JA, *this, Linker, CmdArgs, Inputs));
7125*67e74705SXin Li }
7126*67e74705SXin Li 
getARMArch(StringRef Arch,const llvm::Triple & Triple)7127*67e74705SXin Li const std::string arm::getARMArch(StringRef Arch, const llvm::Triple &Triple) {
7128*67e74705SXin Li   std::string MArch;
7129*67e74705SXin Li   if (!Arch.empty())
7130*67e74705SXin Li     MArch = Arch;
7131*67e74705SXin Li   else
7132*67e74705SXin Li     MArch = Triple.getArchName();
7133*67e74705SXin Li   MArch = StringRef(MArch).split("+").first.lower();
7134*67e74705SXin Li 
7135*67e74705SXin Li   // Handle -march=native.
7136*67e74705SXin Li   if (MArch == "native") {
7137*67e74705SXin Li     std::string CPU = llvm::sys::getHostCPUName();
7138*67e74705SXin Li     if (CPU != "generic") {
7139*67e74705SXin Li       // Translate the native cpu into the architecture suffix for that CPU.
7140*67e74705SXin Li       StringRef Suffix = arm::getLLVMArchSuffixForARM(CPU, MArch, Triple);
7141*67e74705SXin Li       // If there is no valid architecture suffix for this CPU we don't know how
7142*67e74705SXin Li       // to handle it, so return no architecture.
7143*67e74705SXin Li       if (Suffix.empty())
7144*67e74705SXin Li         MArch = "";
7145*67e74705SXin Li       else
7146*67e74705SXin Li         MArch = std::string("arm") + Suffix.str();
7147*67e74705SXin Li     }
7148*67e74705SXin Li   }
7149*67e74705SXin Li 
7150*67e74705SXin Li   return MArch;
7151*67e74705SXin Li }
7152*67e74705SXin Li 
7153*67e74705SXin Li /// Get the (LLVM) name of the minimum ARM CPU for the arch we are targeting.
getARMCPUForMArch(StringRef Arch,const llvm::Triple & Triple)7154*67e74705SXin Li StringRef arm::getARMCPUForMArch(StringRef Arch, const llvm::Triple &Triple) {
7155*67e74705SXin Li   std::string MArch = getARMArch(Arch, Triple);
7156*67e74705SXin Li   // getARMCPUForArch defaults to the triple if MArch is empty, but empty MArch
7157*67e74705SXin Li   // here means an -march=native that we can't handle, so instead return no CPU.
7158*67e74705SXin Li   if (MArch.empty())
7159*67e74705SXin Li     return StringRef();
7160*67e74705SXin Li 
7161*67e74705SXin Li   // We need to return an empty string here on invalid MArch values as the
7162*67e74705SXin Li   // various places that call this function can't cope with a null result.
7163*67e74705SXin Li   return Triple.getARMCPUForArch(MArch);
7164*67e74705SXin Li }
7165*67e74705SXin Li 
7166*67e74705SXin Li /// getARMTargetCPU - Get the (LLVM) name of the ARM cpu we are targeting.
getARMTargetCPU(StringRef CPU,StringRef Arch,const llvm::Triple & Triple)7167*67e74705SXin Li std::string arm::getARMTargetCPU(StringRef CPU, StringRef Arch,
7168*67e74705SXin Li                                  const llvm::Triple &Triple) {
7169*67e74705SXin Li   // FIXME: Warn on inconsistent use of -mcpu and -march.
7170*67e74705SXin Li   // If we have -mcpu=, use that.
7171*67e74705SXin Li   if (!CPU.empty()) {
7172*67e74705SXin Li     std::string MCPU = StringRef(CPU).split("+").first.lower();
7173*67e74705SXin Li     // Handle -mcpu=native.
7174*67e74705SXin Li     if (MCPU == "native")
7175*67e74705SXin Li       return llvm::sys::getHostCPUName();
7176*67e74705SXin Li     else
7177*67e74705SXin Li       return MCPU;
7178*67e74705SXin Li   }
7179*67e74705SXin Li 
7180*67e74705SXin Li   return getARMCPUForMArch(Arch, Triple);
7181*67e74705SXin Li }
7182*67e74705SXin Li 
7183*67e74705SXin Li /// getLLVMArchSuffixForARM - Get the LLVM arch name to use for a particular
7184*67e74705SXin Li /// CPU  (or Arch, if CPU is generic).
7185*67e74705SXin Li // FIXME: This is redundant with -mcpu, why does LLVM use this.
getLLVMArchSuffixForARM(StringRef CPU,StringRef Arch,const llvm::Triple & Triple)7186*67e74705SXin Li StringRef arm::getLLVMArchSuffixForARM(StringRef CPU, StringRef Arch,
7187*67e74705SXin Li                                        const llvm::Triple &Triple) {
7188*67e74705SXin Li   unsigned ArchKind;
7189*67e74705SXin Li   if (CPU == "generic") {
7190*67e74705SXin Li     std::string ARMArch = tools::arm::getARMArch(Arch, Triple);
7191*67e74705SXin Li     ArchKind = llvm::ARM::parseArch(ARMArch);
7192*67e74705SXin Li     if (ArchKind == llvm::ARM::AK_INVALID)
7193*67e74705SXin Li       // In case of generic Arch, i.e. "arm",
7194*67e74705SXin Li       // extract arch from default cpu of the Triple
7195*67e74705SXin Li       ArchKind = llvm::ARM::parseCPUArch(Triple.getARMCPUForArch(ARMArch));
7196*67e74705SXin Li   } else {
7197*67e74705SXin Li     // FIXME: horrible hack to get around the fact that Cortex-A7 is only an
7198*67e74705SXin Li     // armv7k triple if it's actually been specified via "-arch armv7k".
7199*67e74705SXin Li     ArchKind = (Arch == "armv7k" || Arch == "thumbv7k")
7200*67e74705SXin Li                           ? (unsigned)llvm::ARM::AK_ARMV7K
7201*67e74705SXin Li                           : llvm::ARM::parseCPUArch(CPU);
7202*67e74705SXin Li   }
7203*67e74705SXin Li   if (ArchKind == llvm::ARM::AK_INVALID)
7204*67e74705SXin Li     return "";
7205*67e74705SXin Li   return llvm::ARM::getSubArch(ArchKind);
7206*67e74705SXin Li }
7207*67e74705SXin Li 
appendEBLinkFlags(const ArgList & Args,ArgStringList & CmdArgs,const llvm::Triple & Triple)7208*67e74705SXin Li void arm::appendEBLinkFlags(const ArgList &Args, ArgStringList &CmdArgs,
7209*67e74705SXin Li                             const llvm::Triple &Triple) {
7210*67e74705SXin Li   if (Args.hasArg(options::OPT_r))
7211*67e74705SXin Li     return;
7212*67e74705SXin Li 
7213*67e74705SXin Li   // ARMv7 (and later) and ARMv6-M do not support BE-32, so instruct the linker
7214*67e74705SXin Li   // to generate BE-8 executables.
7215*67e74705SXin Li   if (getARMSubArchVersionNumber(Triple) >= 7 || isARMMProfile(Triple))
7216*67e74705SXin Li     CmdArgs.push_back("--be8");
7217*67e74705SXin Li }
7218*67e74705SXin Li 
getSupportedNanEncoding(StringRef & CPU)7219*67e74705SXin Li mips::NanEncoding mips::getSupportedNanEncoding(StringRef &CPU) {
7220*67e74705SXin Li   // Strictly speaking, mips32r2 and mips64r2 are NanLegacy-only since Nan2008
7221*67e74705SXin Li   // was first introduced in Release 3. However, other compilers have
7222*67e74705SXin Li   // traditionally allowed it for Release 2 so we should do the same.
7223*67e74705SXin Li   return (NanEncoding)llvm::StringSwitch<int>(CPU)
7224*67e74705SXin Li       .Case("mips1", NanLegacy)
7225*67e74705SXin Li       .Case("mips2", NanLegacy)
7226*67e74705SXin Li       .Case("mips3", NanLegacy)
7227*67e74705SXin Li       .Case("mips4", NanLegacy)
7228*67e74705SXin Li       .Case("mips5", NanLegacy)
7229*67e74705SXin Li       .Case("mips32", NanLegacy)
7230*67e74705SXin Li       .Case("mips32r2", NanLegacy | Nan2008)
7231*67e74705SXin Li       .Case("mips32r3", NanLegacy | Nan2008)
7232*67e74705SXin Li       .Case("mips32r5", NanLegacy | Nan2008)
7233*67e74705SXin Li       .Case("mips32r6", Nan2008)
7234*67e74705SXin Li       .Case("mips64", NanLegacy)
7235*67e74705SXin Li       .Case("mips64r2", NanLegacy | Nan2008)
7236*67e74705SXin Li       .Case("mips64r3", NanLegacy | Nan2008)
7237*67e74705SXin Li       .Case("mips64r5", NanLegacy | Nan2008)
7238*67e74705SXin Li       .Case("mips64r6", Nan2008)
7239*67e74705SXin Li       .Default(NanLegacy);
7240*67e74705SXin Li }
7241*67e74705SXin Li 
hasCompactBranches(StringRef & CPU)7242*67e74705SXin Li bool mips::hasCompactBranches(StringRef &CPU) {
7243*67e74705SXin Li   // mips32r6 and mips64r6 have compact branches.
7244*67e74705SXin Li   return llvm::StringSwitch<bool>(CPU)
7245*67e74705SXin Li       .Case("mips32r6", true)
7246*67e74705SXin Li       .Case("mips64r6", true)
7247*67e74705SXin Li       .Default(false);
7248*67e74705SXin Li }
7249*67e74705SXin Li 
hasMipsAbiArg(const ArgList & Args,const char * Value)7250*67e74705SXin Li bool mips::hasMipsAbiArg(const ArgList &Args, const char *Value) {
7251*67e74705SXin Li   Arg *A = Args.getLastArg(options::OPT_mabi_EQ);
7252*67e74705SXin Li   return A && (A->getValue() == StringRef(Value));
7253*67e74705SXin Li }
7254*67e74705SXin Li 
isUCLibc(const ArgList & Args)7255*67e74705SXin Li bool mips::isUCLibc(const ArgList &Args) {
7256*67e74705SXin Li   Arg *A = Args.getLastArg(options::OPT_m_libc_Group);
7257*67e74705SXin Li   return A && A->getOption().matches(options::OPT_muclibc);
7258*67e74705SXin Li }
7259*67e74705SXin Li 
isNaN2008(const ArgList & Args,const llvm::Triple & Triple)7260*67e74705SXin Li bool mips::isNaN2008(const ArgList &Args, const llvm::Triple &Triple) {
7261*67e74705SXin Li   if (Arg *NaNArg = Args.getLastArg(options::OPT_mnan_EQ))
7262*67e74705SXin Li     return llvm::StringSwitch<bool>(NaNArg->getValue())
7263*67e74705SXin Li         .Case("2008", true)
7264*67e74705SXin Li         .Case("legacy", false)
7265*67e74705SXin Li         .Default(false);
7266*67e74705SXin Li 
7267*67e74705SXin Li   // NaN2008 is the default for MIPS32r6/MIPS64r6.
7268*67e74705SXin Li   return llvm::StringSwitch<bool>(getCPUName(Args, Triple))
7269*67e74705SXin Li       .Cases("mips32r6", "mips64r6", true)
7270*67e74705SXin Li       .Default(false);
7271*67e74705SXin Li 
7272*67e74705SXin Li   return false;
7273*67e74705SXin Li }
7274*67e74705SXin Li 
isFP64ADefault(const llvm::Triple & Triple,StringRef CPUName)7275*67e74705SXin Li bool mips::isFP64ADefault(const llvm::Triple &Triple, StringRef CPUName) {
7276*67e74705SXin Li   if (!Triple.isAndroid())
7277*67e74705SXin Li     return false;
7278*67e74705SXin Li 
7279*67e74705SXin Li   // Android MIPS32R6 defaults to FP64A.
7280*67e74705SXin Li   return llvm::StringSwitch<bool>(CPUName)
7281*67e74705SXin Li       .Case("mips32r6", true)
7282*67e74705SXin Li       .Default(false);
7283*67e74705SXin Li }
7284*67e74705SXin Li 
isFPXXDefault(const llvm::Triple & Triple,StringRef CPUName,StringRef ABIName,mips::FloatABI FloatABI)7285*67e74705SXin Li bool mips::isFPXXDefault(const llvm::Triple &Triple, StringRef CPUName,
7286*67e74705SXin Li                          StringRef ABIName, mips::FloatABI FloatABI) {
7287*67e74705SXin Li   if (Triple.getVendor() != llvm::Triple::ImaginationTechnologies &&
7288*67e74705SXin Li       Triple.getVendor() != llvm::Triple::MipsTechnologies &&
7289*67e74705SXin Li       !Triple.isAndroid())
7290*67e74705SXin Li     return false;
7291*67e74705SXin Li 
7292*67e74705SXin Li   if (ABIName != "32")
7293*67e74705SXin Li     return false;
7294*67e74705SXin Li 
7295*67e74705SXin Li   // FPXX shouldn't be used if either -msoft-float or -mfloat-abi=soft is
7296*67e74705SXin Li   // present.
7297*67e74705SXin Li   if (FloatABI == mips::FloatABI::Soft)
7298*67e74705SXin Li     return false;
7299*67e74705SXin Li 
7300*67e74705SXin Li   return llvm::StringSwitch<bool>(CPUName)
7301*67e74705SXin Li       .Cases("mips2", "mips3", "mips4", "mips5", true)
7302*67e74705SXin Li       .Cases("mips32", "mips32r2", "mips32r3", "mips32r5", true)
7303*67e74705SXin Li       .Cases("mips64", "mips64r2", "mips64r3", "mips64r5", true)
7304*67e74705SXin Li       .Default(false);
7305*67e74705SXin Li }
7306*67e74705SXin Li 
shouldUseFPXX(const ArgList & Args,const llvm::Triple & Triple,StringRef CPUName,StringRef ABIName,mips::FloatABI FloatABI)7307*67e74705SXin Li bool mips::shouldUseFPXX(const ArgList &Args, const llvm::Triple &Triple,
7308*67e74705SXin Li                          StringRef CPUName, StringRef ABIName,
7309*67e74705SXin Li                          mips::FloatABI FloatABI) {
7310*67e74705SXin Li   bool UseFPXX = isFPXXDefault(Triple, CPUName, ABIName, FloatABI);
7311*67e74705SXin Li 
7312*67e74705SXin Li   // FPXX shouldn't be used if -msingle-float is present.
7313*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_msingle_float,
7314*67e74705SXin Li                                options::OPT_mdouble_float))
7315*67e74705SXin Li     if (A->getOption().matches(options::OPT_msingle_float))
7316*67e74705SXin Li       UseFPXX = false;
7317*67e74705SXin Li 
7318*67e74705SXin Li   return UseFPXX;
7319*67e74705SXin Li }
7320*67e74705SXin Li 
getArchTypeForMachOArchName(StringRef Str)7321*67e74705SXin Li llvm::Triple::ArchType darwin::getArchTypeForMachOArchName(StringRef Str) {
7322*67e74705SXin Li   // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for
7323*67e74705SXin Li   // archs which Darwin doesn't use.
7324*67e74705SXin Li 
7325*67e74705SXin Li   // The matching this routine does is fairly pointless, since it is neither the
7326*67e74705SXin Li   // complete architecture list, nor a reasonable subset. The problem is that
7327*67e74705SXin Li   // historically the driver driver accepts this and also ties its -march=
7328*67e74705SXin Li   // handling to the architecture name, so we need to be careful before removing
7329*67e74705SXin Li   // support for it.
7330*67e74705SXin Li 
7331*67e74705SXin Li   // This code must be kept in sync with Clang's Darwin specific argument
7332*67e74705SXin Li   // translation.
7333*67e74705SXin Li 
7334*67e74705SXin Li   return llvm::StringSwitch<llvm::Triple::ArchType>(Str)
7335*67e74705SXin Li       .Cases("ppc", "ppc601", "ppc603", "ppc604", "ppc604e", llvm::Triple::ppc)
7336*67e74705SXin Li       .Cases("ppc750", "ppc7400", "ppc7450", "ppc970", llvm::Triple::ppc)
7337*67e74705SXin Li       .Case("ppc64", llvm::Triple::ppc64)
7338*67e74705SXin Li       .Cases("i386", "i486", "i486SX", "i586", "i686", llvm::Triple::x86)
7339*67e74705SXin Li       .Cases("pentium", "pentpro", "pentIIm3", "pentIIm5", "pentium4",
7340*67e74705SXin Li              llvm::Triple::x86)
7341*67e74705SXin Li       .Cases("x86_64", "x86_64h", llvm::Triple::x86_64)
7342*67e74705SXin Li       // This is derived from the driver driver.
7343*67e74705SXin Li       .Cases("arm", "armv4t", "armv5", "armv6", "armv6m", llvm::Triple::arm)
7344*67e74705SXin Li       .Cases("armv7", "armv7em", "armv7k", "armv7m", llvm::Triple::arm)
7345*67e74705SXin Li       .Cases("armv7s", "xscale", llvm::Triple::arm)
7346*67e74705SXin Li       .Case("arm64", llvm::Triple::aarch64)
7347*67e74705SXin Li       .Case("r600", llvm::Triple::r600)
7348*67e74705SXin Li       .Case("amdgcn", llvm::Triple::amdgcn)
7349*67e74705SXin Li       .Case("nvptx", llvm::Triple::nvptx)
7350*67e74705SXin Li       .Case("nvptx64", llvm::Triple::nvptx64)
7351*67e74705SXin Li       .Case("amdil", llvm::Triple::amdil)
7352*67e74705SXin Li       .Case("spir", llvm::Triple::spir)
7353*67e74705SXin Li       .Default(llvm::Triple::UnknownArch);
7354*67e74705SXin Li }
7355*67e74705SXin Li 
setTripleTypeForMachOArchName(llvm::Triple & T,StringRef Str)7356*67e74705SXin Li void darwin::setTripleTypeForMachOArchName(llvm::Triple &T, StringRef Str) {
7357*67e74705SXin Li   const llvm::Triple::ArchType Arch = getArchTypeForMachOArchName(Str);
7358*67e74705SXin Li   T.setArch(Arch);
7359*67e74705SXin Li 
7360*67e74705SXin Li   if (Str == "x86_64h")
7361*67e74705SXin Li     T.setArchName(Str);
7362*67e74705SXin Li   else if (Str == "armv6m" || Str == "armv7m" || Str == "armv7em") {
7363*67e74705SXin Li     T.setOS(llvm::Triple::UnknownOS);
7364*67e74705SXin Li     T.setObjectFormat(llvm::Triple::MachO);
7365*67e74705SXin Li   }
7366*67e74705SXin Li }
7367*67e74705SXin Li 
getBaseInputName(const ArgList & Args,const InputInfo & Input)7368*67e74705SXin Li const char *Clang::getBaseInputName(const ArgList &Args,
7369*67e74705SXin Li                                     const InputInfo &Input) {
7370*67e74705SXin Li   return Args.MakeArgString(llvm::sys::path::filename(Input.getBaseInput()));
7371*67e74705SXin Li }
7372*67e74705SXin Li 
getBaseInputStem(const ArgList & Args,const InputInfoList & Inputs)7373*67e74705SXin Li const char *Clang::getBaseInputStem(const ArgList &Args,
7374*67e74705SXin Li                                     const InputInfoList &Inputs) {
7375*67e74705SXin Li   const char *Str = getBaseInputName(Args, Inputs[0]);
7376*67e74705SXin Li 
7377*67e74705SXin Li   if (const char *End = strrchr(Str, '.'))
7378*67e74705SXin Li     return Args.MakeArgString(std::string(Str, End));
7379*67e74705SXin Li 
7380*67e74705SXin Li   return Str;
7381*67e74705SXin Li }
7382*67e74705SXin Li 
getDependencyFileName(const ArgList & Args,const InputInfoList & Inputs)7383*67e74705SXin Li const char *Clang::getDependencyFileName(const ArgList &Args,
7384*67e74705SXin Li                                          const InputInfoList &Inputs) {
7385*67e74705SXin Li   // FIXME: Think about this more.
7386*67e74705SXin Li   std::string Res;
7387*67e74705SXin Li 
7388*67e74705SXin Li   if (Arg *OutputOpt = Args.getLastArg(options::OPT_o)) {
7389*67e74705SXin Li     std::string Str(OutputOpt->getValue());
7390*67e74705SXin Li     Res = Str.substr(0, Str.rfind('.'));
7391*67e74705SXin Li   } else {
7392*67e74705SXin Li     Res = getBaseInputStem(Args, Inputs);
7393*67e74705SXin Li   }
7394*67e74705SXin Li   return Args.MakeArgString(Res + ".d");
7395*67e74705SXin Li }
7396*67e74705SXin Li 
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const7397*67e74705SXin Li void cloudabi::Linker::ConstructJob(Compilation &C, const JobAction &JA,
7398*67e74705SXin Li                                     const InputInfo &Output,
7399*67e74705SXin Li                                     const InputInfoList &Inputs,
7400*67e74705SXin Li                                     const ArgList &Args,
7401*67e74705SXin Li                                     const char *LinkingOutput) const {
7402*67e74705SXin Li   const ToolChain &ToolChain = getToolChain();
7403*67e74705SXin Li   const Driver &D = ToolChain.getDriver();
7404*67e74705SXin Li   ArgStringList CmdArgs;
7405*67e74705SXin Li 
7406*67e74705SXin Li   // Silence warning for "clang -g foo.o -o foo"
7407*67e74705SXin Li   Args.ClaimAllArgs(options::OPT_g_Group);
7408*67e74705SXin Li   // and "clang -emit-llvm foo.o -o foo"
7409*67e74705SXin Li   Args.ClaimAllArgs(options::OPT_emit_llvm);
7410*67e74705SXin Li   // and for "clang -w foo.o -o foo". Other warning options are already
7411*67e74705SXin Li   // handled somewhere else.
7412*67e74705SXin Li   Args.ClaimAllArgs(options::OPT_w);
7413*67e74705SXin Li 
7414*67e74705SXin Li   if (!D.SysRoot.empty())
7415*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
7416*67e74705SXin Li 
7417*67e74705SXin Li   // CloudABI only supports static linkage.
7418*67e74705SXin Li   CmdArgs.push_back("-Bstatic");
7419*67e74705SXin Li 
7420*67e74705SXin Li   // CloudABI uses Position Independent Executables exclusively.
7421*67e74705SXin Li   CmdArgs.push_back("-pie");
7422*67e74705SXin Li   CmdArgs.push_back("--no-dynamic-linker");
7423*67e74705SXin Li   CmdArgs.push_back("-zrelro");
7424*67e74705SXin Li 
7425*67e74705SXin Li   CmdArgs.push_back("--eh-frame-hdr");
7426*67e74705SXin Li   CmdArgs.push_back("--gc-sections");
7427*67e74705SXin Li 
7428*67e74705SXin Li   if (Output.isFilename()) {
7429*67e74705SXin Li     CmdArgs.push_back("-o");
7430*67e74705SXin Li     CmdArgs.push_back(Output.getFilename());
7431*67e74705SXin Li   } else {
7432*67e74705SXin Li     assert(Output.isNothing() && "Invalid output.");
7433*67e74705SXin Li   }
7434*67e74705SXin Li 
7435*67e74705SXin Li   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
7436*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crt0.o")));
7437*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtbegin.o")));
7438*67e74705SXin Li   }
7439*67e74705SXin Li 
7440*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_L);
7441*67e74705SXin Li   ToolChain.AddFilePathLibArgs(Args, CmdArgs);
7442*67e74705SXin Li   Args.AddAllArgs(CmdArgs,
7443*67e74705SXin Li                   {options::OPT_T_Group, options::OPT_e, options::OPT_s,
7444*67e74705SXin Li                    options::OPT_t, options::OPT_Z_Flag, options::OPT_r});
7445*67e74705SXin Li 
7446*67e74705SXin Li   if (D.isUsingLTO())
7447*67e74705SXin Li     AddGoldPlugin(ToolChain, Args, CmdArgs, D.getLTOMode() == LTOK_Thin);
7448*67e74705SXin Li 
7449*67e74705SXin Li   AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
7450*67e74705SXin Li 
7451*67e74705SXin Li   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
7452*67e74705SXin Li     if (D.CCCIsCXX())
7453*67e74705SXin Li       ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
7454*67e74705SXin Li     CmdArgs.push_back("-lc");
7455*67e74705SXin Li     CmdArgs.push_back("-lcompiler_rt");
7456*67e74705SXin Li   }
7457*67e74705SXin Li 
7458*67e74705SXin Li   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles))
7459*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtend.o")));
7460*67e74705SXin Li 
7461*67e74705SXin Li   const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath());
7462*67e74705SXin Li   C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
7463*67e74705SXin Li }
7464*67e74705SXin Li 
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const7465*67e74705SXin Li void darwin::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
7466*67e74705SXin Li                                      const InputInfo &Output,
7467*67e74705SXin Li                                      const InputInfoList &Inputs,
7468*67e74705SXin Li                                      const ArgList &Args,
7469*67e74705SXin Li                                      const char *LinkingOutput) const {
7470*67e74705SXin Li   ArgStringList CmdArgs;
7471*67e74705SXin Li 
7472*67e74705SXin Li   assert(Inputs.size() == 1 && "Unexpected number of inputs.");
7473*67e74705SXin Li   const InputInfo &Input = Inputs[0];
7474*67e74705SXin Li 
7475*67e74705SXin Li   // Determine the original source input.
7476*67e74705SXin Li   const Action *SourceAction = &JA;
7477*67e74705SXin Li   while (SourceAction->getKind() != Action::InputClass) {
7478*67e74705SXin Li     assert(!SourceAction->getInputs().empty() && "unexpected root action!");
7479*67e74705SXin Li     SourceAction = SourceAction->getInputs()[0];
7480*67e74705SXin Li   }
7481*67e74705SXin Li 
7482*67e74705SXin Li   // If -fno-integrated-as is used add -Q to the darwin assember driver to make
7483*67e74705SXin Li   // sure it runs its system assembler not clang's integrated assembler.
7484*67e74705SXin Li   // Applicable to darwin11+ and Xcode 4+.  darwin<10 lacked integrated-as.
7485*67e74705SXin Li   // FIXME: at run-time detect assembler capabilities or rely on version
7486*67e74705SXin Li   // information forwarded by -target-assembler-version.
7487*67e74705SXin Li   if (Args.hasArg(options::OPT_fno_integrated_as)) {
7488*67e74705SXin Li     const llvm::Triple &T(getToolChain().getTriple());
7489*67e74705SXin Li     if (!(T.isMacOSX() && T.isMacOSXVersionLT(10, 7)))
7490*67e74705SXin Li       CmdArgs.push_back("-Q");
7491*67e74705SXin Li   }
7492*67e74705SXin Li 
7493*67e74705SXin Li   // Forward -g, assuming we are dealing with an actual assembly file.
7494*67e74705SXin Li   if (SourceAction->getType() == types::TY_Asm ||
7495*67e74705SXin Li       SourceAction->getType() == types::TY_PP_Asm) {
7496*67e74705SXin Li     if (Args.hasArg(options::OPT_gstabs))
7497*67e74705SXin Li       CmdArgs.push_back("--gstabs");
7498*67e74705SXin Li     else if (Args.hasArg(options::OPT_g_Group))
7499*67e74705SXin Li       CmdArgs.push_back("-g");
7500*67e74705SXin Li   }
7501*67e74705SXin Li 
7502*67e74705SXin Li   // Derived from asm spec.
7503*67e74705SXin Li   AddMachOArch(Args, CmdArgs);
7504*67e74705SXin Li 
7505*67e74705SXin Li   // Use -force_cpusubtype_ALL on x86 by default.
7506*67e74705SXin Li   if (getToolChain().getArch() == llvm::Triple::x86 ||
7507*67e74705SXin Li       getToolChain().getArch() == llvm::Triple::x86_64 ||
7508*67e74705SXin Li       Args.hasArg(options::OPT_force__cpusubtype__ALL))
7509*67e74705SXin Li     CmdArgs.push_back("-force_cpusubtype_ALL");
7510*67e74705SXin Li 
7511*67e74705SXin Li   if (getToolChain().getArch() != llvm::Triple::x86_64 &&
7512*67e74705SXin Li       (((Args.hasArg(options::OPT_mkernel) ||
7513*67e74705SXin Li          Args.hasArg(options::OPT_fapple_kext)) &&
7514*67e74705SXin Li         getMachOToolChain().isKernelStatic()) ||
7515*67e74705SXin Li        Args.hasArg(options::OPT_static)))
7516*67e74705SXin Li     CmdArgs.push_back("-static");
7517*67e74705SXin Li 
7518*67e74705SXin Li   Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
7519*67e74705SXin Li 
7520*67e74705SXin Li   assert(Output.isFilename() && "Unexpected lipo output.");
7521*67e74705SXin Li   CmdArgs.push_back("-o");
7522*67e74705SXin Li   CmdArgs.push_back(Output.getFilename());
7523*67e74705SXin Li 
7524*67e74705SXin Li   assert(Input.isFilename() && "Invalid input.");
7525*67e74705SXin Li   CmdArgs.push_back(Input.getFilename());
7526*67e74705SXin Li 
7527*67e74705SXin Li   // asm_final spec is empty.
7528*67e74705SXin Li 
7529*67e74705SXin Li   const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
7530*67e74705SXin Li   C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
7531*67e74705SXin Li }
7532*67e74705SXin Li 
anchor()7533*67e74705SXin Li void darwin::MachOTool::anchor() {}
7534*67e74705SXin Li 
AddMachOArch(const ArgList & Args,ArgStringList & CmdArgs) const7535*67e74705SXin Li void darwin::MachOTool::AddMachOArch(const ArgList &Args,
7536*67e74705SXin Li                                      ArgStringList &CmdArgs) const {
7537*67e74705SXin Li   StringRef ArchName = getMachOToolChain().getMachOArchName(Args);
7538*67e74705SXin Li 
7539*67e74705SXin Li   // Derived from darwin_arch spec.
7540*67e74705SXin Li   CmdArgs.push_back("-arch");
7541*67e74705SXin Li   CmdArgs.push_back(Args.MakeArgString(ArchName));
7542*67e74705SXin Li 
7543*67e74705SXin Li   // FIXME: Is this needed anymore?
7544*67e74705SXin Li   if (ArchName == "arm")
7545*67e74705SXin Li     CmdArgs.push_back("-force_cpusubtype_ALL");
7546*67e74705SXin Li }
7547*67e74705SXin Li 
NeedsTempPath(const InputInfoList & Inputs) const7548*67e74705SXin Li bool darwin::Linker::NeedsTempPath(const InputInfoList &Inputs) const {
7549*67e74705SXin Li   // We only need to generate a temp path for LTO if we aren't compiling object
7550*67e74705SXin Li   // files. When compiling source files, we run 'dsymutil' after linking. We
7551*67e74705SXin Li   // don't run 'dsymutil' when compiling object files.
7552*67e74705SXin Li   for (const auto &Input : Inputs)
7553*67e74705SXin Li     if (Input.getType() != types::TY_Object)
7554*67e74705SXin Li       return true;
7555*67e74705SXin Li 
7556*67e74705SXin Li   return false;
7557*67e74705SXin Li }
7558*67e74705SXin Li 
AddLinkArgs(Compilation & C,const ArgList & Args,ArgStringList & CmdArgs,const InputInfoList & Inputs) const7559*67e74705SXin Li void darwin::Linker::AddLinkArgs(Compilation &C, const ArgList &Args,
7560*67e74705SXin Li                                  ArgStringList &CmdArgs,
7561*67e74705SXin Li                                  const InputInfoList &Inputs) const {
7562*67e74705SXin Li   const Driver &D = getToolChain().getDriver();
7563*67e74705SXin Li   const toolchains::MachO &MachOTC = getMachOToolChain();
7564*67e74705SXin Li 
7565*67e74705SXin Li   unsigned Version[5] = {0, 0, 0, 0, 0};
7566*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ)) {
7567*67e74705SXin Li     if (!Driver::GetReleaseVersion(A->getValue(), Version))
7568*67e74705SXin Li       D.Diag(diag::err_drv_invalid_version_number) << A->getAsString(Args);
7569*67e74705SXin Li   }
7570*67e74705SXin Li 
7571*67e74705SXin Li   // Newer linkers support -demangle. Pass it if supported and not disabled by
7572*67e74705SXin Li   // the user.
7573*67e74705SXin Li   if (Version[0] >= 100 && !Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
7574*67e74705SXin Li     CmdArgs.push_back("-demangle");
7575*67e74705SXin Li 
7576*67e74705SXin Li   if (Args.hasArg(options::OPT_rdynamic) && Version[0] >= 137)
7577*67e74705SXin Li     CmdArgs.push_back("-export_dynamic");
7578*67e74705SXin Li 
7579*67e74705SXin Li   // If we are using App Extension restrictions, pass a flag to the linker
7580*67e74705SXin Li   // telling it that the compiled code has been audited.
7581*67e74705SXin Li   if (Args.hasFlag(options::OPT_fapplication_extension,
7582*67e74705SXin Li                    options::OPT_fno_application_extension, false))
7583*67e74705SXin Li     CmdArgs.push_back("-application_extension");
7584*67e74705SXin Li 
7585*67e74705SXin Li   if (D.isUsingLTO()) {
7586*67e74705SXin Li     // If we are using LTO, then automatically create a temporary file path for
7587*67e74705SXin Li     // the linker to use, so that it's lifetime will extend past a possible
7588*67e74705SXin Li     // dsymutil step.
7589*67e74705SXin Li     if (Version[0] >= 116 && NeedsTempPath(Inputs)) {
7590*67e74705SXin Li       const char *TmpPath = C.getArgs().MakeArgString(
7591*67e74705SXin Li           D.GetTemporaryPath("cc", types::getTypeTempSuffix(types::TY_Object)));
7592*67e74705SXin Li       C.addTempFile(TmpPath);
7593*67e74705SXin Li       CmdArgs.push_back("-object_path_lto");
7594*67e74705SXin Li       CmdArgs.push_back(TmpPath);
7595*67e74705SXin Li     }
7596*67e74705SXin Li 
7597*67e74705SXin Li     // Use -lto_library option to specify the libLTO.dylib path. Try to find
7598*67e74705SXin Li     // it in clang installed libraries. If not found, the option is not used
7599*67e74705SXin Li     // and 'ld' will use its default mechanism to search for libLTO.dylib.
7600*67e74705SXin Li     if (Version[0] >= 133) {
7601*67e74705SXin Li       // Search for libLTO in <InstalledDir>/../lib/libLTO.dylib
7602*67e74705SXin Li       StringRef P = llvm::sys::path::parent_path(D.getInstalledDir());
7603*67e74705SXin Li       SmallString<128> LibLTOPath(P);
7604*67e74705SXin Li       llvm::sys::path::append(LibLTOPath, "lib");
7605*67e74705SXin Li       llvm::sys::path::append(LibLTOPath, "libLTO.dylib");
7606*67e74705SXin Li       if (llvm::sys::fs::exists(LibLTOPath)) {
7607*67e74705SXin Li         CmdArgs.push_back("-lto_library");
7608*67e74705SXin Li         CmdArgs.push_back(C.getArgs().MakeArgString(LibLTOPath));
7609*67e74705SXin Li       } else {
7610*67e74705SXin Li         D.Diag(diag::warn_drv_lto_libpath);
7611*67e74705SXin Li       }
7612*67e74705SXin Li     }
7613*67e74705SXin Li   }
7614*67e74705SXin Li 
7615*67e74705SXin Li   // Derived from the "link" spec.
7616*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_static);
7617*67e74705SXin Li   if (!Args.hasArg(options::OPT_static))
7618*67e74705SXin Li     CmdArgs.push_back("-dynamic");
7619*67e74705SXin Li   if (Args.hasArg(options::OPT_fgnu_runtime)) {
7620*67e74705SXin Li     // FIXME: gcc replaces -lobjc in forward args with -lobjc-gnu
7621*67e74705SXin Li     // here. How do we wish to handle such things?
7622*67e74705SXin Li   }
7623*67e74705SXin Li 
7624*67e74705SXin Li   if (!Args.hasArg(options::OPT_dynamiclib)) {
7625*67e74705SXin Li     AddMachOArch(Args, CmdArgs);
7626*67e74705SXin Li     // FIXME: Why do this only on this path?
7627*67e74705SXin Li     Args.AddLastArg(CmdArgs, options::OPT_force__cpusubtype__ALL);
7628*67e74705SXin Li 
7629*67e74705SXin Li     Args.AddLastArg(CmdArgs, options::OPT_bundle);
7630*67e74705SXin Li     Args.AddAllArgs(CmdArgs, options::OPT_bundle__loader);
7631*67e74705SXin Li     Args.AddAllArgs(CmdArgs, options::OPT_client__name);
7632*67e74705SXin Li 
7633*67e74705SXin Li     Arg *A;
7634*67e74705SXin Li     if ((A = Args.getLastArg(options::OPT_compatibility__version)) ||
7635*67e74705SXin Li         (A = Args.getLastArg(options::OPT_current__version)) ||
7636*67e74705SXin Li         (A = Args.getLastArg(options::OPT_install__name)))
7637*67e74705SXin Li       D.Diag(diag::err_drv_argument_only_allowed_with) << A->getAsString(Args)
7638*67e74705SXin Li                                                        << "-dynamiclib";
7639*67e74705SXin Li 
7640*67e74705SXin Li     Args.AddLastArg(CmdArgs, options::OPT_force__flat__namespace);
7641*67e74705SXin Li     Args.AddLastArg(CmdArgs, options::OPT_keep__private__externs);
7642*67e74705SXin Li     Args.AddLastArg(CmdArgs, options::OPT_private__bundle);
7643*67e74705SXin Li   } else {
7644*67e74705SXin Li     CmdArgs.push_back("-dylib");
7645*67e74705SXin Li 
7646*67e74705SXin Li     Arg *A;
7647*67e74705SXin Li     if ((A = Args.getLastArg(options::OPT_bundle)) ||
7648*67e74705SXin Li         (A = Args.getLastArg(options::OPT_bundle__loader)) ||
7649*67e74705SXin Li         (A = Args.getLastArg(options::OPT_client__name)) ||
7650*67e74705SXin Li         (A = Args.getLastArg(options::OPT_force__flat__namespace)) ||
7651*67e74705SXin Li         (A = Args.getLastArg(options::OPT_keep__private__externs)) ||
7652*67e74705SXin Li         (A = Args.getLastArg(options::OPT_private__bundle)))
7653*67e74705SXin Li       D.Diag(diag::err_drv_argument_not_allowed_with) << A->getAsString(Args)
7654*67e74705SXin Li                                                       << "-dynamiclib";
7655*67e74705SXin Li 
7656*67e74705SXin Li     Args.AddAllArgsTranslated(CmdArgs, options::OPT_compatibility__version,
7657*67e74705SXin Li                               "-dylib_compatibility_version");
7658*67e74705SXin Li     Args.AddAllArgsTranslated(CmdArgs, options::OPT_current__version,
7659*67e74705SXin Li                               "-dylib_current_version");
7660*67e74705SXin Li 
7661*67e74705SXin Li     AddMachOArch(Args, CmdArgs);
7662*67e74705SXin Li 
7663*67e74705SXin Li     Args.AddAllArgsTranslated(CmdArgs, options::OPT_install__name,
7664*67e74705SXin Li                               "-dylib_install_name");
7665*67e74705SXin Li   }
7666*67e74705SXin Li 
7667*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_all__load);
7668*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_allowable__client);
7669*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_bind__at__load);
7670*67e74705SXin Li   if (MachOTC.isTargetIOSBased())
7671*67e74705SXin Li     Args.AddLastArg(CmdArgs, options::OPT_arch__errors__fatal);
7672*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_dead__strip);
7673*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_no__dead__strip__inits__and__terms);
7674*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_dylib__file);
7675*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_dynamic);
7676*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_exported__symbols__list);
7677*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_flat__namespace);
7678*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_force__load);
7679*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_headerpad__max__install__names);
7680*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_image__base);
7681*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_init);
7682*67e74705SXin Li 
7683*67e74705SXin Li   // Add the deployment target.
7684*67e74705SXin Li   MachOTC.addMinVersionArgs(Args, CmdArgs);
7685*67e74705SXin Li 
7686*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_nomultidefs);
7687*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_multi__module);
7688*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_single__module);
7689*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined);
7690*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined__unused);
7691*67e74705SXin Li 
7692*67e74705SXin Li   if (const Arg *A =
7693*67e74705SXin Li           Args.getLastArg(options::OPT_fpie, options::OPT_fPIE,
7694*67e74705SXin Li                           options::OPT_fno_pie, options::OPT_fno_PIE)) {
7695*67e74705SXin Li     if (A->getOption().matches(options::OPT_fpie) ||
7696*67e74705SXin Li         A->getOption().matches(options::OPT_fPIE))
7697*67e74705SXin Li       CmdArgs.push_back("-pie");
7698*67e74705SXin Li     else
7699*67e74705SXin Li       CmdArgs.push_back("-no_pie");
7700*67e74705SXin Li   }
7701*67e74705SXin Li   // for embed-bitcode, use -bitcode_bundle in linker command
7702*67e74705SXin Li   if (C.getDriver().embedBitcodeEnabled() ||
7703*67e74705SXin Li       C.getDriver().embedBitcodeMarkerOnly()) {
7704*67e74705SXin Li     // Check if the toolchain supports bitcode build flow.
7705*67e74705SXin Li     if (MachOTC.SupportsEmbeddedBitcode())
7706*67e74705SXin Li       CmdArgs.push_back("-bitcode_bundle");
7707*67e74705SXin Li     else
7708*67e74705SXin Li       D.Diag(diag::err_drv_bitcode_unsupported_on_toolchain);
7709*67e74705SXin Li   }
7710*67e74705SXin Li 
7711*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_prebind);
7712*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_noprebind);
7713*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_nofixprebinding);
7714*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_prebind__all__twolevel__modules);
7715*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_read__only__relocs);
7716*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_sectcreate);
7717*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_sectorder);
7718*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_seg1addr);
7719*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_segprot);
7720*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_segaddr);
7721*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_segs__read__only__addr);
7722*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_segs__read__write__addr);
7723*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_seg__addr__table);
7724*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_seg__addr__table__filename);
7725*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_sub__library);
7726*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_sub__umbrella);
7727*67e74705SXin Li 
7728*67e74705SXin Li   // Give --sysroot= preference, over the Apple specific behavior to also use
7729*67e74705SXin Li   // --isysroot as the syslibroot.
7730*67e74705SXin Li   StringRef sysroot = C.getSysRoot();
7731*67e74705SXin Li   if (sysroot != "") {
7732*67e74705SXin Li     CmdArgs.push_back("-syslibroot");
7733*67e74705SXin Li     CmdArgs.push_back(C.getArgs().MakeArgString(sysroot));
7734*67e74705SXin Li   } else if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
7735*67e74705SXin Li     CmdArgs.push_back("-syslibroot");
7736*67e74705SXin Li     CmdArgs.push_back(A->getValue());
7737*67e74705SXin Li   }
7738*67e74705SXin Li 
7739*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace);
7740*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace__hints);
7741*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_umbrella);
7742*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_undefined);
7743*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_unexported__symbols__list);
7744*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_weak__reference__mismatches);
7745*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_X_Flag);
7746*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_y);
7747*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_w);
7748*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_pagezero__size);
7749*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_segs__read__);
7750*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_seglinkedit);
7751*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_noseglinkedit);
7752*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_sectalign);
7753*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_sectobjectsymbols);
7754*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_segcreate);
7755*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_whyload);
7756*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_whatsloaded);
7757*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_dylinker__install__name);
7758*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_dylinker);
7759*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_Mach);
7760*67e74705SXin Li }
7761*67e74705SXin Li 
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const7762*67e74705SXin Li void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA,
7763*67e74705SXin Li                                   const InputInfo &Output,
7764*67e74705SXin Li                                   const InputInfoList &Inputs,
7765*67e74705SXin Li                                   const ArgList &Args,
7766*67e74705SXin Li                                   const char *LinkingOutput) const {
7767*67e74705SXin Li   assert(Output.getType() == types::TY_Image && "Invalid linker output type.");
7768*67e74705SXin Li 
7769*67e74705SXin Li   // If the number of arguments surpasses the system limits, we will encode the
7770*67e74705SXin Li   // input files in a separate file, shortening the command line. To this end,
7771*67e74705SXin Li   // build a list of input file names that can be passed via a file with the
7772*67e74705SXin Li   // -filelist linker option.
7773*67e74705SXin Li   llvm::opt::ArgStringList InputFileList;
7774*67e74705SXin Li 
7775*67e74705SXin Li   // The logic here is derived from gcc's behavior; most of which
7776*67e74705SXin Li   // comes from specs (starting with link_command). Consult gcc for
7777*67e74705SXin Li   // more information.
7778*67e74705SXin Li   ArgStringList CmdArgs;
7779*67e74705SXin Li 
7780*67e74705SXin Li   /// Hack(tm) to ignore linking errors when we are doing ARC migration.
7781*67e74705SXin Li   if (Args.hasArg(options::OPT_ccc_arcmt_check,
7782*67e74705SXin Li                   options::OPT_ccc_arcmt_migrate)) {
7783*67e74705SXin Li     for (const auto &Arg : Args)
7784*67e74705SXin Li       Arg->claim();
7785*67e74705SXin Li     const char *Exec =
7786*67e74705SXin Li         Args.MakeArgString(getToolChain().GetProgramPath("touch"));
7787*67e74705SXin Li     CmdArgs.push_back(Output.getFilename());
7788*67e74705SXin Li     C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, None));
7789*67e74705SXin Li     return;
7790*67e74705SXin Li   }
7791*67e74705SXin Li 
7792*67e74705SXin Li   // I'm not sure why this particular decomposition exists in gcc, but
7793*67e74705SXin Li   // we follow suite for ease of comparison.
7794*67e74705SXin Li   AddLinkArgs(C, Args, CmdArgs, Inputs);
7795*67e74705SXin Li 
7796*67e74705SXin Li   // It seems that the 'e' option is completely ignored for dynamic executables
7797*67e74705SXin Li   // (the default), and with static executables, the last one wins, as expected.
7798*67e74705SXin Li   Args.AddAllArgs(CmdArgs, {options::OPT_d_Flag, options::OPT_s, options::OPT_t,
7799*67e74705SXin Li                             options::OPT_Z_Flag, options::OPT_u_Group,
7800*67e74705SXin Li                             options::OPT_e, options::OPT_r});
7801*67e74705SXin Li 
7802*67e74705SXin Li   // Forward -ObjC when either -ObjC or -ObjC++ is used, to force loading
7803*67e74705SXin Li   // members of static archive libraries which implement Objective-C classes or
7804*67e74705SXin Li   // categories.
7805*67e74705SXin Li   if (Args.hasArg(options::OPT_ObjC) || Args.hasArg(options::OPT_ObjCXX))
7806*67e74705SXin Li     CmdArgs.push_back("-ObjC");
7807*67e74705SXin Li 
7808*67e74705SXin Li   CmdArgs.push_back("-o");
7809*67e74705SXin Li   CmdArgs.push_back(Output.getFilename());
7810*67e74705SXin Li 
7811*67e74705SXin Li   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles))
7812*67e74705SXin Li     getMachOToolChain().addStartObjectFileArgs(Args, CmdArgs);
7813*67e74705SXin Li 
7814*67e74705SXin Li   // SafeStack requires its own runtime libraries
7815*67e74705SXin Li   // These libraries should be linked first, to make sure the
7816*67e74705SXin Li   // __safestack_init constructor executes before everything else
7817*67e74705SXin Li   if (getToolChain().getSanitizerArgs().needsSafeStackRt()) {
7818*67e74705SXin Li     getMachOToolChain().AddLinkRuntimeLib(Args, CmdArgs,
7819*67e74705SXin Li                                           "libclang_rt.safestack_osx.a",
7820*67e74705SXin Li                                           /*AlwaysLink=*/true);
7821*67e74705SXin Li   }
7822*67e74705SXin Li 
7823*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_L);
7824*67e74705SXin Li 
7825*67e74705SXin Li   AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
7826*67e74705SXin Li   // Build the input file for -filelist (list of linker input files) in case we
7827*67e74705SXin Li   // need it later
7828*67e74705SXin Li   for (const auto &II : Inputs) {
7829*67e74705SXin Li     if (!II.isFilename()) {
7830*67e74705SXin Li       // This is a linker input argument.
7831*67e74705SXin Li       // We cannot mix input arguments and file names in a -filelist input, thus
7832*67e74705SXin Li       // we prematurely stop our list (remaining files shall be passed as
7833*67e74705SXin Li       // arguments).
7834*67e74705SXin Li       if (InputFileList.size() > 0)
7835*67e74705SXin Li         break;
7836*67e74705SXin Li 
7837*67e74705SXin Li       continue;
7838*67e74705SXin Li     }
7839*67e74705SXin Li 
7840*67e74705SXin Li     InputFileList.push_back(II.getFilename());
7841*67e74705SXin Li   }
7842*67e74705SXin Li 
7843*67e74705SXin Li   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs))
7844*67e74705SXin Li     addOpenMPRuntime(CmdArgs, getToolChain(), Args);
7845*67e74705SXin Li 
7846*67e74705SXin Li   if (isObjCRuntimeLinked(Args) &&
7847*67e74705SXin Li       !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
7848*67e74705SXin Li     // We use arclite library for both ARC and subscripting support.
7849*67e74705SXin Li     getMachOToolChain().AddLinkARCArgs(Args, CmdArgs);
7850*67e74705SXin Li 
7851*67e74705SXin Li     CmdArgs.push_back("-framework");
7852*67e74705SXin Li     CmdArgs.push_back("Foundation");
7853*67e74705SXin Li     // Link libobj.
7854*67e74705SXin Li     CmdArgs.push_back("-lobjc");
7855*67e74705SXin Li   }
7856*67e74705SXin Li 
7857*67e74705SXin Li   if (LinkingOutput) {
7858*67e74705SXin Li     CmdArgs.push_back("-arch_multiple");
7859*67e74705SXin Li     CmdArgs.push_back("-final_output");
7860*67e74705SXin Li     CmdArgs.push_back(LinkingOutput);
7861*67e74705SXin Li   }
7862*67e74705SXin Li 
7863*67e74705SXin Li   if (Args.hasArg(options::OPT_fnested_functions))
7864*67e74705SXin Li     CmdArgs.push_back("-allow_stack_execute");
7865*67e74705SXin Li 
7866*67e74705SXin Li   getMachOToolChain().addProfileRTLibs(Args, CmdArgs);
7867*67e74705SXin Li 
7868*67e74705SXin Li   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
7869*67e74705SXin Li     if (getToolChain().getDriver().CCCIsCXX())
7870*67e74705SXin Li       getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
7871*67e74705SXin Li 
7872*67e74705SXin Li     // link_ssp spec is empty.
7873*67e74705SXin Li 
7874*67e74705SXin Li     // Let the tool chain choose which runtime library to link.
7875*67e74705SXin Li     getMachOToolChain().AddLinkRuntimeLibArgs(Args, CmdArgs);
7876*67e74705SXin Li   }
7877*67e74705SXin Li 
7878*67e74705SXin Li   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
7879*67e74705SXin Li     // endfile_spec is empty.
7880*67e74705SXin Li   }
7881*67e74705SXin Li 
7882*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
7883*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_F);
7884*67e74705SXin Li 
7885*67e74705SXin Li   // -iframework should be forwarded as -F.
7886*67e74705SXin Li   for (const Arg *A : Args.filtered(options::OPT_iframework))
7887*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(std::string("-F") + A->getValue()));
7888*67e74705SXin Li 
7889*67e74705SXin Li   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
7890*67e74705SXin Li     if (Arg *A = Args.getLastArg(options::OPT_fveclib)) {
7891*67e74705SXin Li       if (A->getValue() == StringRef("Accelerate")) {
7892*67e74705SXin Li         CmdArgs.push_back("-framework");
7893*67e74705SXin Li         CmdArgs.push_back("Accelerate");
7894*67e74705SXin Li       }
7895*67e74705SXin Li     }
7896*67e74705SXin Li   }
7897*67e74705SXin Li 
7898*67e74705SXin Li   const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
7899*67e74705SXin Li   std::unique_ptr<Command> Cmd =
7900*67e74705SXin Li       llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs);
7901*67e74705SXin Li   Cmd->setInputFileList(std::move(InputFileList));
7902*67e74705SXin Li   C.addCommand(std::move(Cmd));
7903*67e74705SXin Li }
7904*67e74705SXin Li 
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const7905*67e74705SXin Li void darwin::Lipo::ConstructJob(Compilation &C, const JobAction &JA,
7906*67e74705SXin Li                                 const InputInfo &Output,
7907*67e74705SXin Li                                 const InputInfoList &Inputs,
7908*67e74705SXin Li                                 const ArgList &Args,
7909*67e74705SXin Li                                 const char *LinkingOutput) const {
7910*67e74705SXin Li   ArgStringList CmdArgs;
7911*67e74705SXin Li 
7912*67e74705SXin Li   CmdArgs.push_back("-create");
7913*67e74705SXin Li   assert(Output.isFilename() && "Unexpected lipo output.");
7914*67e74705SXin Li 
7915*67e74705SXin Li   CmdArgs.push_back("-output");
7916*67e74705SXin Li   CmdArgs.push_back(Output.getFilename());
7917*67e74705SXin Li 
7918*67e74705SXin Li   for (const auto &II : Inputs) {
7919*67e74705SXin Li     assert(II.isFilename() && "Unexpected lipo input.");
7920*67e74705SXin Li     CmdArgs.push_back(II.getFilename());
7921*67e74705SXin Li   }
7922*67e74705SXin Li 
7923*67e74705SXin Li   const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("lipo"));
7924*67e74705SXin Li   C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
7925*67e74705SXin Li }
7926*67e74705SXin Li 
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const7927*67e74705SXin Li void darwin::Dsymutil::ConstructJob(Compilation &C, const JobAction &JA,
7928*67e74705SXin Li                                     const InputInfo &Output,
7929*67e74705SXin Li                                     const InputInfoList &Inputs,
7930*67e74705SXin Li                                     const ArgList &Args,
7931*67e74705SXin Li                                     const char *LinkingOutput) const {
7932*67e74705SXin Li   ArgStringList CmdArgs;
7933*67e74705SXin Li 
7934*67e74705SXin Li   CmdArgs.push_back("-o");
7935*67e74705SXin Li   CmdArgs.push_back(Output.getFilename());
7936*67e74705SXin Li 
7937*67e74705SXin Li   assert(Inputs.size() == 1 && "Unable to handle multiple inputs.");
7938*67e74705SXin Li   const InputInfo &Input = Inputs[0];
7939*67e74705SXin Li   assert(Input.isFilename() && "Unexpected dsymutil input.");
7940*67e74705SXin Li   CmdArgs.push_back(Input.getFilename());
7941*67e74705SXin Li 
7942*67e74705SXin Li   const char *Exec =
7943*67e74705SXin Li       Args.MakeArgString(getToolChain().GetProgramPath("dsymutil"));
7944*67e74705SXin Li   C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
7945*67e74705SXin Li }
7946*67e74705SXin Li 
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const7947*67e74705SXin Li void darwin::VerifyDebug::ConstructJob(Compilation &C, const JobAction &JA,
7948*67e74705SXin Li                                        const InputInfo &Output,
7949*67e74705SXin Li                                        const InputInfoList &Inputs,
7950*67e74705SXin Li                                        const ArgList &Args,
7951*67e74705SXin Li                                        const char *LinkingOutput) const {
7952*67e74705SXin Li   ArgStringList CmdArgs;
7953*67e74705SXin Li   CmdArgs.push_back("--verify");
7954*67e74705SXin Li   CmdArgs.push_back("--debug-info");
7955*67e74705SXin Li   CmdArgs.push_back("--eh-frame");
7956*67e74705SXin Li   CmdArgs.push_back("--quiet");
7957*67e74705SXin Li 
7958*67e74705SXin Li   assert(Inputs.size() == 1 && "Unable to handle multiple inputs.");
7959*67e74705SXin Li   const InputInfo &Input = Inputs[0];
7960*67e74705SXin Li   assert(Input.isFilename() && "Unexpected verify input");
7961*67e74705SXin Li 
7962*67e74705SXin Li   // Grabbing the output of the earlier dsymutil run.
7963*67e74705SXin Li   CmdArgs.push_back(Input.getFilename());
7964*67e74705SXin Li 
7965*67e74705SXin Li   const char *Exec =
7966*67e74705SXin Li       Args.MakeArgString(getToolChain().GetProgramPath("dwarfdump"));
7967*67e74705SXin Li   C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
7968*67e74705SXin Li }
7969*67e74705SXin Li 
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const7970*67e74705SXin Li void solaris::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
7971*67e74705SXin Li                                       const InputInfo &Output,
7972*67e74705SXin Li                                       const InputInfoList &Inputs,
7973*67e74705SXin Li                                       const ArgList &Args,
7974*67e74705SXin Li                                       const char *LinkingOutput) const {
7975*67e74705SXin Li   claimNoWarnArgs(Args);
7976*67e74705SXin Li   ArgStringList CmdArgs;
7977*67e74705SXin Li 
7978*67e74705SXin Li   Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
7979*67e74705SXin Li 
7980*67e74705SXin Li   CmdArgs.push_back("-o");
7981*67e74705SXin Li   CmdArgs.push_back(Output.getFilename());
7982*67e74705SXin Li 
7983*67e74705SXin Li   for (const auto &II : Inputs)
7984*67e74705SXin Li     CmdArgs.push_back(II.getFilename());
7985*67e74705SXin Li 
7986*67e74705SXin Li   const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
7987*67e74705SXin Li   C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
7988*67e74705SXin Li }
7989*67e74705SXin Li 
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const7990*67e74705SXin Li void solaris::Linker::ConstructJob(Compilation &C, const JobAction &JA,
7991*67e74705SXin Li                                    const InputInfo &Output,
7992*67e74705SXin Li                                    const InputInfoList &Inputs,
7993*67e74705SXin Li                                    const ArgList &Args,
7994*67e74705SXin Li                                    const char *LinkingOutput) const {
7995*67e74705SXin Li   ArgStringList CmdArgs;
7996*67e74705SXin Li 
7997*67e74705SXin Li   // Demangle C++ names in errors
7998*67e74705SXin Li   CmdArgs.push_back("-C");
7999*67e74705SXin Li 
8000*67e74705SXin Li   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_shared)) {
8001*67e74705SXin Li     CmdArgs.push_back("-e");
8002*67e74705SXin Li     CmdArgs.push_back("_start");
8003*67e74705SXin Li   }
8004*67e74705SXin Li 
8005*67e74705SXin Li   if (Args.hasArg(options::OPT_static)) {
8006*67e74705SXin Li     CmdArgs.push_back("-Bstatic");
8007*67e74705SXin Li     CmdArgs.push_back("-dn");
8008*67e74705SXin Li   } else {
8009*67e74705SXin Li     CmdArgs.push_back("-Bdynamic");
8010*67e74705SXin Li     if (Args.hasArg(options::OPT_shared)) {
8011*67e74705SXin Li       CmdArgs.push_back("-shared");
8012*67e74705SXin Li     } else {
8013*67e74705SXin Li       CmdArgs.push_back("--dynamic-linker");
8014*67e74705SXin Li       CmdArgs.push_back(
8015*67e74705SXin Li           Args.MakeArgString(getToolChain().GetFilePath("ld.so.1")));
8016*67e74705SXin Li     }
8017*67e74705SXin Li   }
8018*67e74705SXin Li 
8019*67e74705SXin Li   if (Output.isFilename()) {
8020*67e74705SXin Li     CmdArgs.push_back("-o");
8021*67e74705SXin Li     CmdArgs.push_back(Output.getFilename());
8022*67e74705SXin Li   } else {
8023*67e74705SXin Li     assert(Output.isNothing() && "Invalid output.");
8024*67e74705SXin Li   }
8025*67e74705SXin Li 
8026*67e74705SXin Li   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
8027*67e74705SXin Li     if (!Args.hasArg(options::OPT_shared))
8028*67e74705SXin Li       CmdArgs.push_back(
8029*67e74705SXin Li           Args.MakeArgString(getToolChain().GetFilePath("crt1.o")));
8030*67e74705SXin Li 
8031*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crti.o")));
8032*67e74705SXin Li     CmdArgs.push_back(
8033*67e74705SXin Li         Args.MakeArgString(getToolChain().GetFilePath("values-Xa.o")));
8034*67e74705SXin Li     CmdArgs.push_back(
8035*67e74705SXin Li         Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o")));
8036*67e74705SXin Li   }
8037*67e74705SXin Li 
8038*67e74705SXin Li   getToolChain().AddFilePathLibArgs(Args, CmdArgs);
8039*67e74705SXin Li 
8040*67e74705SXin Li   Args.AddAllArgs(CmdArgs, {options::OPT_L, options::OPT_T_Group,
8041*67e74705SXin Li                             options::OPT_e, options::OPT_r});
8042*67e74705SXin Li 
8043*67e74705SXin Li   AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
8044*67e74705SXin Li 
8045*67e74705SXin Li   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
8046*67e74705SXin Li     if (getToolChain().getDriver().CCCIsCXX())
8047*67e74705SXin Li       getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
8048*67e74705SXin Li     CmdArgs.push_back("-lgcc_s");
8049*67e74705SXin Li     CmdArgs.push_back("-lc");
8050*67e74705SXin Li     if (!Args.hasArg(options::OPT_shared)) {
8051*67e74705SXin Li       CmdArgs.push_back("-lgcc");
8052*67e74705SXin Li       CmdArgs.push_back("-lm");
8053*67e74705SXin Li     }
8054*67e74705SXin Li   }
8055*67e74705SXin Li 
8056*67e74705SXin Li   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
8057*67e74705SXin Li     CmdArgs.push_back(
8058*67e74705SXin Li         Args.MakeArgString(getToolChain().GetFilePath("crtend.o")));
8059*67e74705SXin Li   }
8060*67e74705SXin Li   CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtn.o")));
8061*67e74705SXin Li 
8062*67e74705SXin Li   getToolChain().addProfileRTLibs(Args, CmdArgs);
8063*67e74705SXin Li 
8064*67e74705SXin Li   const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
8065*67e74705SXin Li   C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
8066*67e74705SXin Li }
8067*67e74705SXin Li 
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const8068*67e74705SXin Li void openbsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
8069*67e74705SXin Li                                       const InputInfo &Output,
8070*67e74705SXin Li                                       const InputInfoList &Inputs,
8071*67e74705SXin Li                                       const ArgList &Args,
8072*67e74705SXin Li                                       const char *LinkingOutput) const {
8073*67e74705SXin Li   claimNoWarnArgs(Args);
8074*67e74705SXin Li   ArgStringList CmdArgs;
8075*67e74705SXin Li 
8076*67e74705SXin Li   switch (getToolChain().getArch()) {
8077*67e74705SXin Li   case llvm::Triple::x86:
8078*67e74705SXin Li     // When building 32-bit code on OpenBSD/amd64, we have to explicitly
8079*67e74705SXin Li     // instruct as in the base system to assemble 32-bit code.
8080*67e74705SXin Li     CmdArgs.push_back("--32");
8081*67e74705SXin Li     break;
8082*67e74705SXin Li 
8083*67e74705SXin Li   case llvm::Triple::ppc:
8084*67e74705SXin Li     CmdArgs.push_back("-mppc");
8085*67e74705SXin Li     CmdArgs.push_back("-many");
8086*67e74705SXin Li     break;
8087*67e74705SXin Li 
8088*67e74705SXin Li   case llvm::Triple::sparc:
8089*67e74705SXin Li   case llvm::Triple::sparcel: {
8090*67e74705SXin Li     CmdArgs.push_back("-32");
8091*67e74705SXin Li     std::string CPU = getCPUName(Args, getToolChain().getTriple());
8092*67e74705SXin Li     CmdArgs.push_back(getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
8093*67e74705SXin Li     AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
8094*67e74705SXin Li     break;
8095*67e74705SXin Li   }
8096*67e74705SXin Li 
8097*67e74705SXin Li   case llvm::Triple::sparcv9: {
8098*67e74705SXin Li     CmdArgs.push_back("-64");
8099*67e74705SXin Li     std::string CPU = getCPUName(Args, getToolChain().getTriple());
8100*67e74705SXin Li     CmdArgs.push_back(getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
8101*67e74705SXin Li     AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
8102*67e74705SXin Li     break;
8103*67e74705SXin Li   }
8104*67e74705SXin Li 
8105*67e74705SXin Li   case llvm::Triple::mips64:
8106*67e74705SXin Li   case llvm::Triple::mips64el: {
8107*67e74705SXin Li     StringRef CPUName;
8108*67e74705SXin Li     StringRef ABIName;
8109*67e74705SXin Li     mips::getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName);
8110*67e74705SXin Li 
8111*67e74705SXin Li     CmdArgs.push_back("-mabi");
8112*67e74705SXin Li     CmdArgs.push_back(getGnuCompatibleMipsABIName(ABIName).data());
8113*67e74705SXin Li 
8114*67e74705SXin Li     if (getToolChain().getArch() == llvm::Triple::mips64)
8115*67e74705SXin Li       CmdArgs.push_back("-EB");
8116*67e74705SXin Li     else
8117*67e74705SXin Li       CmdArgs.push_back("-EL");
8118*67e74705SXin Li 
8119*67e74705SXin Li     AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
8120*67e74705SXin Li     break;
8121*67e74705SXin Li   }
8122*67e74705SXin Li 
8123*67e74705SXin Li   default:
8124*67e74705SXin Li     break;
8125*67e74705SXin Li   }
8126*67e74705SXin Li 
8127*67e74705SXin Li   Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
8128*67e74705SXin Li 
8129*67e74705SXin Li   CmdArgs.push_back("-o");
8130*67e74705SXin Li   CmdArgs.push_back(Output.getFilename());
8131*67e74705SXin Li 
8132*67e74705SXin Li   for (const auto &II : Inputs)
8133*67e74705SXin Li     CmdArgs.push_back(II.getFilename());
8134*67e74705SXin Li 
8135*67e74705SXin Li   const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
8136*67e74705SXin Li   C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
8137*67e74705SXin Li }
8138*67e74705SXin Li 
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const8139*67e74705SXin Li void openbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
8140*67e74705SXin Li                                    const InputInfo &Output,
8141*67e74705SXin Li                                    const InputInfoList &Inputs,
8142*67e74705SXin Li                                    const ArgList &Args,
8143*67e74705SXin Li                                    const char *LinkingOutput) const {
8144*67e74705SXin Li   const Driver &D = getToolChain().getDriver();
8145*67e74705SXin Li   ArgStringList CmdArgs;
8146*67e74705SXin Li 
8147*67e74705SXin Li   // Silence warning for "clang -g foo.o -o foo"
8148*67e74705SXin Li   Args.ClaimAllArgs(options::OPT_g_Group);
8149*67e74705SXin Li   // and "clang -emit-llvm foo.o -o foo"
8150*67e74705SXin Li   Args.ClaimAllArgs(options::OPT_emit_llvm);
8151*67e74705SXin Li   // and for "clang -w foo.o -o foo". Other warning options are already
8152*67e74705SXin Li   // handled somewhere else.
8153*67e74705SXin Li   Args.ClaimAllArgs(options::OPT_w);
8154*67e74705SXin Li 
8155*67e74705SXin Li   if (getToolChain().getArch() == llvm::Triple::mips64)
8156*67e74705SXin Li     CmdArgs.push_back("-EB");
8157*67e74705SXin Li   else if (getToolChain().getArch() == llvm::Triple::mips64el)
8158*67e74705SXin Li     CmdArgs.push_back("-EL");
8159*67e74705SXin Li 
8160*67e74705SXin Li   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_shared)) {
8161*67e74705SXin Li     CmdArgs.push_back("-e");
8162*67e74705SXin Li     CmdArgs.push_back("__start");
8163*67e74705SXin Li   }
8164*67e74705SXin Li 
8165*67e74705SXin Li   if (Args.hasArg(options::OPT_static)) {
8166*67e74705SXin Li     CmdArgs.push_back("-Bstatic");
8167*67e74705SXin Li   } else {
8168*67e74705SXin Li     if (Args.hasArg(options::OPT_rdynamic))
8169*67e74705SXin Li       CmdArgs.push_back("-export-dynamic");
8170*67e74705SXin Li     CmdArgs.push_back("--eh-frame-hdr");
8171*67e74705SXin Li     CmdArgs.push_back("-Bdynamic");
8172*67e74705SXin Li     if (Args.hasArg(options::OPT_shared)) {
8173*67e74705SXin Li       CmdArgs.push_back("-shared");
8174*67e74705SXin Li     } else {
8175*67e74705SXin Li       CmdArgs.push_back("-dynamic-linker");
8176*67e74705SXin Li       CmdArgs.push_back("/usr/libexec/ld.so");
8177*67e74705SXin Li     }
8178*67e74705SXin Li   }
8179*67e74705SXin Li 
8180*67e74705SXin Li   if (Args.hasArg(options::OPT_nopie))
8181*67e74705SXin Li     CmdArgs.push_back("-nopie");
8182*67e74705SXin Li 
8183*67e74705SXin Li   if (Output.isFilename()) {
8184*67e74705SXin Li     CmdArgs.push_back("-o");
8185*67e74705SXin Li     CmdArgs.push_back(Output.getFilename());
8186*67e74705SXin Li   } else {
8187*67e74705SXin Li     assert(Output.isNothing() && "Invalid output.");
8188*67e74705SXin Li   }
8189*67e74705SXin Li 
8190*67e74705SXin Li   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
8191*67e74705SXin Li     if (!Args.hasArg(options::OPT_shared)) {
8192*67e74705SXin Li       if (Args.hasArg(options::OPT_pg))
8193*67e74705SXin Li         CmdArgs.push_back(
8194*67e74705SXin Li             Args.MakeArgString(getToolChain().GetFilePath("gcrt0.o")));
8195*67e74705SXin Li       else
8196*67e74705SXin Li         CmdArgs.push_back(
8197*67e74705SXin Li             Args.MakeArgString(getToolChain().GetFilePath("crt0.o")));
8198*67e74705SXin Li       CmdArgs.push_back(
8199*67e74705SXin Li           Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o")));
8200*67e74705SXin Li     } else {
8201*67e74705SXin Li       CmdArgs.push_back(
8202*67e74705SXin Li           Args.MakeArgString(getToolChain().GetFilePath("crtbeginS.o")));
8203*67e74705SXin Li     }
8204*67e74705SXin Li   }
8205*67e74705SXin Li 
8206*67e74705SXin Li   std::string Triple = getToolChain().getTripleString();
8207*67e74705SXin Li   if (Triple.substr(0, 6) == "x86_64")
8208*67e74705SXin Li     Triple.replace(0, 6, "amd64");
8209*67e74705SXin Li   CmdArgs.push_back(
8210*67e74705SXin Li       Args.MakeArgString("-L/usr/lib/gcc-lib/" + Triple + "/4.2.1"));
8211*67e74705SXin Li 
8212*67e74705SXin Li   Args.AddAllArgs(CmdArgs, {options::OPT_L, options::OPT_T_Group,
8213*67e74705SXin Li                             options::OPT_e, options::OPT_s, options::OPT_t,
8214*67e74705SXin Li                             options::OPT_Z_Flag, options::OPT_r});
8215*67e74705SXin Li 
8216*67e74705SXin Li   AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
8217*67e74705SXin Li 
8218*67e74705SXin Li   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
8219*67e74705SXin Li     if (D.CCCIsCXX()) {
8220*67e74705SXin Li       getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
8221*67e74705SXin Li       if (Args.hasArg(options::OPT_pg))
8222*67e74705SXin Li         CmdArgs.push_back("-lm_p");
8223*67e74705SXin Li       else
8224*67e74705SXin Li         CmdArgs.push_back("-lm");
8225*67e74705SXin Li     }
8226*67e74705SXin Li 
8227*67e74705SXin Li     // FIXME: For some reason GCC passes -lgcc before adding
8228*67e74705SXin Li     // the default system libraries. Just mimic this for now.
8229*67e74705SXin Li     CmdArgs.push_back("-lgcc");
8230*67e74705SXin Li 
8231*67e74705SXin Li     if (Args.hasArg(options::OPT_pthread)) {
8232*67e74705SXin Li       if (!Args.hasArg(options::OPT_shared) && Args.hasArg(options::OPT_pg))
8233*67e74705SXin Li         CmdArgs.push_back("-lpthread_p");
8234*67e74705SXin Li       else
8235*67e74705SXin Li         CmdArgs.push_back("-lpthread");
8236*67e74705SXin Li     }
8237*67e74705SXin Li 
8238*67e74705SXin Li     if (!Args.hasArg(options::OPT_shared)) {
8239*67e74705SXin Li       if (Args.hasArg(options::OPT_pg))
8240*67e74705SXin Li         CmdArgs.push_back("-lc_p");
8241*67e74705SXin Li       else
8242*67e74705SXin Li         CmdArgs.push_back("-lc");
8243*67e74705SXin Li     }
8244*67e74705SXin Li 
8245*67e74705SXin Li     CmdArgs.push_back("-lgcc");
8246*67e74705SXin Li   }
8247*67e74705SXin Li 
8248*67e74705SXin Li   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
8249*67e74705SXin Li     if (!Args.hasArg(options::OPT_shared))
8250*67e74705SXin Li       CmdArgs.push_back(
8251*67e74705SXin Li           Args.MakeArgString(getToolChain().GetFilePath("crtend.o")));
8252*67e74705SXin Li     else
8253*67e74705SXin Li       CmdArgs.push_back(
8254*67e74705SXin Li           Args.MakeArgString(getToolChain().GetFilePath("crtendS.o")));
8255*67e74705SXin Li   }
8256*67e74705SXin Li 
8257*67e74705SXin Li   const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
8258*67e74705SXin Li   C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
8259*67e74705SXin Li }
8260*67e74705SXin Li 
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const8261*67e74705SXin Li void bitrig::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
8262*67e74705SXin Li                                      const InputInfo &Output,
8263*67e74705SXin Li                                      const InputInfoList &Inputs,
8264*67e74705SXin Li                                      const ArgList &Args,
8265*67e74705SXin Li                                      const char *LinkingOutput) const {
8266*67e74705SXin Li   claimNoWarnArgs(Args);
8267*67e74705SXin Li   ArgStringList CmdArgs;
8268*67e74705SXin Li 
8269*67e74705SXin Li   Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
8270*67e74705SXin Li 
8271*67e74705SXin Li   CmdArgs.push_back("-o");
8272*67e74705SXin Li   CmdArgs.push_back(Output.getFilename());
8273*67e74705SXin Li 
8274*67e74705SXin Li   for (const auto &II : Inputs)
8275*67e74705SXin Li     CmdArgs.push_back(II.getFilename());
8276*67e74705SXin Li 
8277*67e74705SXin Li   const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
8278*67e74705SXin Li   C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
8279*67e74705SXin Li }
8280*67e74705SXin Li 
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const8281*67e74705SXin Li void bitrig::Linker::ConstructJob(Compilation &C, const JobAction &JA,
8282*67e74705SXin Li                                   const InputInfo &Output,
8283*67e74705SXin Li                                   const InputInfoList &Inputs,
8284*67e74705SXin Li                                   const ArgList &Args,
8285*67e74705SXin Li                                   const char *LinkingOutput) const {
8286*67e74705SXin Li   const Driver &D = getToolChain().getDriver();
8287*67e74705SXin Li   ArgStringList CmdArgs;
8288*67e74705SXin Li 
8289*67e74705SXin Li   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_shared)) {
8290*67e74705SXin Li     CmdArgs.push_back("-e");
8291*67e74705SXin Li     CmdArgs.push_back("__start");
8292*67e74705SXin Li   }
8293*67e74705SXin Li 
8294*67e74705SXin Li   if (Args.hasArg(options::OPT_static)) {
8295*67e74705SXin Li     CmdArgs.push_back("-Bstatic");
8296*67e74705SXin Li   } else {
8297*67e74705SXin Li     if (Args.hasArg(options::OPT_rdynamic))
8298*67e74705SXin Li       CmdArgs.push_back("-export-dynamic");
8299*67e74705SXin Li     CmdArgs.push_back("--eh-frame-hdr");
8300*67e74705SXin Li     CmdArgs.push_back("-Bdynamic");
8301*67e74705SXin Li     if (Args.hasArg(options::OPT_shared)) {
8302*67e74705SXin Li       CmdArgs.push_back("-shared");
8303*67e74705SXin Li     } else {
8304*67e74705SXin Li       CmdArgs.push_back("-dynamic-linker");
8305*67e74705SXin Li       CmdArgs.push_back("/usr/libexec/ld.so");
8306*67e74705SXin Li     }
8307*67e74705SXin Li   }
8308*67e74705SXin Li 
8309*67e74705SXin Li   if (Output.isFilename()) {
8310*67e74705SXin Li     CmdArgs.push_back("-o");
8311*67e74705SXin Li     CmdArgs.push_back(Output.getFilename());
8312*67e74705SXin Li   } else {
8313*67e74705SXin Li     assert(Output.isNothing() && "Invalid output.");
8314*67e74705SXin Li   }
8315*67e74705SXin Li 
8316*67e74705SXin Li   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
8317*67e74705SXin Li     if (!Args.hasArg(options::OPT_shared)) {
8318*67e74705SXin Li       if (Args.hasArg(options::OPT_pg))
8319*67e74705SXin Li         CmdArgs.push_back(
8320*67e74705SXin Li             Args.MakeArgString(getToolChain().GetFilePath("gcrt0.o")));
8321*67e74705SXin Li       else
8322*67e74705SXin Li         CmdArgs.push_back(
8323*67e74705SXin Li             Args.MakeArgString(getToolChain().GetFilePath("crt0.o")));
8324*67e74705SXin Li       CmdArgs.push_back(
8325*67e74705SXin Li           Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o")));
8326*67e74705SXin Li     } else {
8327*67e74705SXin Li       CmdArgs.push_back(
8328*67e74705SXin Li           Args.MakeArgString(getToolChain().GetFilePath("crtbeginS.o")));
8329*67e74705SXin Li     }
8330*67e74705SXin Li   }
8331*67e74705SXin Li 
8332*67e74705SXin Li   Args.AddAllArgs(CmdArgs,
8333*67e74705SXin Li                   {options::OPT_L, options::OPT_T_Group, options::OPT_e});
8334*67e74705SXin Li 
8335*67e74705SXin Li   AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
8336*67e74705SXin Li 
8337*67e74705SXin Li   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
8338*67e74705SXin Li     if (D.CCCIsCXX()) {
8339*67e74705SXin Li       getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
8340*67e74705SXin Li       if (Args.hasArg(options::OPT_pg))
8341*67e74705SXin Li         CmdArgs.push_back("-lm_p");
8342*67e74705SXin Li       else
8343*67e74705SXin Li         CmdArgs.push_back("-lm");
8344*67e74705SXin Li     }
8345*67e74705SXin Li 
8346*67e74705SXin Li     if (Args.hasArg(options::OPT_pthread)) {
8347*67e74705SXin Li       if (!Args.hasArg(options::OPT_shared) && Args.hasArg(options::OPT_pg))
8348*67e74705SXin Li         CmdArgs.push_back("-lpthread_p");
8349*67e74705SXin Li       else
8350*67e74705SXin Li         CmdArgs.push_back("-lpthread");
8351*67e74705SXin Li     }
8352*67e74705SXin Li 
8353*67e74705SXin Li     if (!Args.hasArg(options::OPT_shared)) {
8354*67e74705SXin Li       if (Args.hasArg(options::OPT_pg))
8355*67e74705SXin Li         CmdArgs.push_back("-lc_p");
8356*67e74705SXin Li       else
8357*67e74705SXin Li         CmdArgs.push_back("-lc");
8358*67e74705SXin Li     }
8359*67e74705SXin Li 
8360*67e74705SXin Li     StringRef MyArch;
8361*67e74705SXin Li     switch (getToolChain().getArch()) {
8362*67e74705SXin Li     case llvm::Triple::arm:
8363*67e74705SXin Li       MyArch = "arm";
8364*67e74705SXin Li       break;
8365*67e74705SXin Li     case llvm::Triple::x86:
8366*67e74705SXin Li       MyArch = "i386";
8367*67e74705SXin Li       break;
8368*67e74705SXin Li     case llvm::Triple::x86_64:
8369*67e74705SXin Li       MyArch = "amd64";
8370*67e74705SXin Li       break;
8371*67e74705SXin Li     default:
8372*67e74705SXin Li       llvm_unreachable("Unsupported architecture");
8373*67e74705SXin Li     }
8374*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString("-lclang_rt." + MyArch));
8375*67e74705SXin Li   }
8376*67e74705SXin Li 
8377*67e74705SXin Li   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
8378*67e74705SXin Li     if (!Args.hasArg(options::OPT_shared))
8379*67e74705SXin Li       CmdArgs.push_back(
8380*67e74705SXin Li           Args.MakeArgString(getToolChain().GetFilePath("crtend.o")));
8381*67e74705SXin Li     else
8382*67e74705SXin Li       CmdArgs.push_back(
8383*67e74705SXin Li           Args.MakeArgString(getToolChain().GetFilePath("crtendS.o")));
8384*67e74705SXin Li   }
8385*67e74705SXin Li 
8386*67e74705SXin Li   const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
8387*67e74705SXin Li   C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
8388*67e74705SXin Li }
8389*67e74705SXin Li 
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const8390*67e74705SXin Li void freebsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
8391*67e74705SXin Li                                       const InputInfo &Output,
8392*67e74705SXin Li                                       const InputInfoList &Inputs,
8393*67e74705SXin Li                                       const ArgList &Args,
8394*67e74705SXin Li                                       const char *LinkingOutput) const {
8395*67e74705SXin Li   claimNoWarnArgs(Args);
8396*67e74705SXin Li   ArgStringList CmdArgs;
8397*67e74705SXin Li 
8398*67e74705SXin Li   // When building 32-bit code on FreeBSD/amd64, we have to explicitly
8399*67e74705SXin Li   // instruct as in the base system to assemble 32-bit code.
8400*67e74705SXin Li   switch (getToolChain().getArch()) {
8401*67e74705SXin Li   default:
8402*67e74705SXin Li     break;
8403*67e74705SXin Li   case llvm::Triple::x86:
8404*67e74705SXin Li     CmdArgs.push_back("--32");
8405*67e74705SXin Li     break;
8406*67e74705SXin Li   case llvm::Triple::ppc:
8407*67e74705SXin Li     CmdArgs.push_back("-a32");
8408*67e74705SXin Li     break;
8409*67e74705SXin Li   case llvm::Triple::mips:
8410*67e74705SXin Li   case llvm::Triple::mipsel:
8411*67e74705SXin Li   case llvm::Triple::mips64:
8412*67e74705SXin Li   case llvm::Triple::mips64el: {
8413*67e74705SXin Li     StringRef CPUName;
8414*67e74705SXin Li     StringRef ABIName;
8415*67e74705SXin Li     mips::getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName);
8416*67e74705SXin Li 
8417*67e74705SXin Li     CmdArgs.push_back("-march");
8418*67e74705SXin Li     CmdArgs.push_back(CPUName.data());
8419*67e74705SXin Li 
8420*67e74705SXin Li     CmdArgs.push_back("-mabi");
8421*67e74705SXin Li     CmdArgs.push_back(getGnuCompatibleMipsABIName(ABIName).data());
8422*67e74705SXin Li 
8423*67e74705SXin Li     if (getToolChain().getArch() == llvm::Triple::mips ||
8424*67e74705SXin Li         getToolChain().getArch() == llvm::Triple::mips64)
8425*67e74705SXin Li       CmdArgs.push_back("-EB");
8426*67e74705SXin Li     else
8427*67e74705SXin Li       CmdArgs.push_back("-EL");
8428*67e74705SXin Li 
8429*67e74705SXin Li     if (Arg *A = Args.getLastArg(options::OPT_G)) {
8430*67e74705SXin Li       StringRef v = A->getValue();
8431*67e74705SXin Li       CmdArgs.push_back(Args.MakeArgString("-G" + v));
8432*67e74705SXin Li       A->claim();
8433*67e74705SXin Li     }
8434*67e74705SXin Li 
8435*67e74705SXin Li     AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
8436*67e74705SXin Li     break;
8437*67e74705SXin Li   }
8438*67e74705SXin Li   case llvm::Triple::arm:
8439*67e74705SXin Li   case llvm::Triple::armeb:
8440*67e74705SXin Li   case llvm::Triple::thumb:
8441*67e74705SXin Li   case llvm::Triple::thumbeb: {
8442*67e74705SXin Li     arm::FloatABI ABI = arm::getARMFloatABI(getToolChain(), Args);
8443*67e74705SXin Li 
8444*67e74705SXin Li     if (ABI == arm::FloatABI::Hard)
8445*67e74705SXin Li       CmdArgs.push_back("-mfpu=vfp");
8446*67e74705SXin Li     else
8447*67e74705SXin Li       CmdArgs.push_back("-mfpu=softvfp");
8448*67e74705SXin Li 
8449*67e74705SXin Li     switch (getToolChain().getTriple().getEnvironment()) {
8450*67e74705SXin Li     case llvm::Triple::GNUEABIHF:
8451*67e74705SXin Li     case llvm::Triple::GNUEABI:
8452*67e74705SXin Li     case llvm::Triple::EABI:
8453*67e74705SXin Li       CmdArgs.push_back("-meabi=5");
8454*67e74705SXin Li       break;
8455*67e74705SXin Li 
8456*67e74705SXin Li     default:
8457*67e74705SXin Li       CmdArgs.push_back("-matpcs");
8458*67e74705SXin Li     }
8459*67e74705SXin Li     break;
8460*67e74705SXin Li   }
8461*67e74705SXin Li   case llvm::Triple::sparc:
8462*67e74705SXin Li   case llvm::Triple::sparcel:
8463*67e74705SXin Li   case llvm::Triple::sparcv9: {
8464*67e74705SXin Li     std::string CPU = getCPUName(Args, getToolChain().getTriple());
8465*67e74705SXin Li     CmdArgs.push_back(getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
8466*67e74705SXin Li     AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
8467*67e74705SXin Li     break;
8468*67e74705SXin Li   }
8469*67e74705SXin Li   }
8470*67e74705SXin Li 
8471*67e74705SXin Li   Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
8472*67e74705SXin Li 
8473*67e74705SXin Li   CmdArgs.push_back("-o");
8474*67e74705SXin Li   CmdArgs.push_back(Output.getFilename());
8475*67e74705SXin Li 
8476*67e74705SXin Li   for (const auto &II : Inputs)
8477*67e74705SXin Li     CmdArgs.push_back(II.getFilename());
8478*67e74705SXin Li 
8479*67e74705SXin Li   const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
8480*67e74705SXin Li   C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
8481*67e74705SXin Li }
8482*67e74705SXin Li 
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const8483*67e74705SXin Li void freebsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
8484*67e74705SXin Li                                    const InputInfo &Output,
8485*67e74705SXin Li                                    const InputInfoList &Inputs,
8486*67e74705SXin Li                                    const ArgList &Args,
8487*67e74705SXin Li                                    const char *LinkingOutput) const {
8488*67e74705SXin Li   const toolchains::FreeBSD &ToolChain =
8489*67e74705SXin Li       static_cast<const toolchains::FreeBSD &>(getToolChain());
8490*67e74705SXin Li   const Driver &D = ToolChain.getDriver();
8491*67e74705SXin Li   const llvm::Triple::ArchType Arch = ToolChain.getArch();
8492*67e74705SXin Li   const bool IsPIE =
8493*67e74705SXin Li       !Args.hasArg(options::OPT_shared) &&
8494*67e74705SXin Li       (Args.hasArg(options::OPT_pie) || ToolChain.isPIEDefault());
8495*67e74705SXin Li   ArgStringList CmdArgs;
8496*67e74705SXin Li 
8497*67e74705SXin Li   // Silence warning for "clang -g foo.o -o foo"
8498*67e74705SXin Li   Args.ClaimAllArgs(options::OPT_g_Group);
8499*67e74705SXin Li   // and "clang -emit-llvm foo.o -o foo"
8500*67e74705SXin Li   Args.ClaimAllArgs(options::OPT_emit_llvm);
8501*67e74705SXin Li   // and for "clang -w foo.o -o foo". Other warning options are already
8502*67e74705SXin Li   // handled somewhere else.
8503*67e74705SXin Li   Args.ClaimAllArgs(options::OPT_w);
8504*67e74705SXin Li 
8505*67e74705SXin Li   if (!D.SysRoot.empty())
8506*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
8507*67e74705SXin Li 
8508*67e74705SXin Li   if (IsPIE)
8509*67e74705SXin Li     CmdArgs.push_back("-pie");
8510*67e74705SXin Li 
8511*67e74705SXin Li   CmdArgs.push_back("--eh-frame-hdr");
8512*67e74705SXin Li   if (Args.hasArg(options::OPT_static)) {
8513*67e74705SXin Li     CmdArgs.push_back("-Bstatic");
8514*67e74705SXin Li   } else {
8515*67e74705SXin Li     if (Args.hasArg(options::OPT_rdynamic))
8516*67e74705SXin Li       CmdArgs.push_back("-export-dynamic");
8517*67e74705SXin Li     if (Args.hasArg(options::OPT_shared)) {
8518*67e74705SXin Li       CmdArgs.push_back("-Bshareable");
8519*67e74705SXin Li     } else {
8520*67e74705SXin Li       CmdArgs.push_back("-dynamic-linker");
8521*67e74705SXin Li       CmdArgs.push_back("/libexec/ld-elf.so.1");
8522*67e74705SXin Li     }
8523*67e74705SXin Li     if (ToolChain.getTriple().getOSMajorVersion() >= 9) {
8524*67e74705SXin Li       if (Arch == llvm::Triple::arm || Arch == llvm::Triple::sparc ||
8525*67e74705SXin Li           Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64) {
8526*67e74705SXin Li         CmdArgs.push_back("--hash-style=both");
8527*67e74705SXin Li       }
8528*67e74705SXin Li     }
8529*67e74705SXin Li     CmdArgs.push_back("--enable-new-dtags");
8530*67e74705SXin Li   }
8531*67e74705SXin Li 
8532*67e74705SXin Li   // When building 32-bit code on FreeBSD/amd64, we have to explicitly
8533*67e74705SXin Li   // instruct ld in the base system to link 32-bit code.
8534*67e74705SXin Li   if (Arch == llvm::Triple::x86) {
8535*67e74705SXin Li     CmdArgs.push_back("-m");
8536*67e74705SXin Li     CmdArgs.push_back("elf_i386_fbsd");
8537*67e74705SXin Li   }
8538*67e74705SXin Li 
8539*67e74705SXin Li   if (Arch == llvm::Triple::ppc) {
8540*67e74705SXin Li     CmdArgs.push_back("-m");
8541*67e74705SXin Li     CmdArgs.push_back("elf32ppc_fbsd");
8542*67e74705SXin Li   }
8543*67e74705SXin Li 
8544*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_G)) {
8545*67e74705SXin Li     if (ToolChain.getArch() == llvm::Triple::mips ||
8546*67e74705SXin Li       ToolChain.getArch() == llvm::Triple::mipsel ||
8547*67e74705SXin Li       ToolChain.getArch() == llvm::Triple::mips64 ||
8548*67e74705SXin Li       ToolChain.getArch() == llvm::Triple::mips64el) {
8549*67e74705SXin Li       StringRef v = A->getValue();
8550*67e74705SXin Li       CmdArgs.push_back(Args.MakeArgString("-G" + v));
8551*67e74705SXin Li       A->claim();
8552*67e74705SXin Li     }
8553*67e74705SXin Li   }
8554*67e74705SXin Li 
8555*67e74705SXin Li   if (Output.isFilename()) {
8556*67e74705SXin Li     CmdArgs.push_back("-o");
8557*67e74705SXin Li     CmdArgs.push_back(Output.getFilename());
8558*67e74705SXin Li   } else {
8559*67e74705SXin Li     assert(Output.isNothing() && "Invalid output.");
8560*67e74705SXin Li   }
8561*67e74705SXin Li 
8562*67e74705SXin Li   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
8563*67e74705SXin Li     const char *crt1 = nullptr;
8564*67e74705SXin Li     if (!Args.hasArg(options::OPT_shared)) {
8565*67e74705SXin Li       if (Args.hasArg(options::OPT_pg))
8566*67e74705SXin Li         crt1 = "gcrt1.o";
8567*67e74705SXin Li       else if (IsPIE)
8568*67e74705SXin Li         crt1 = "Scrt1.o";
8569*67e74705SXin Li       else
8570*67e74705SXin Li         crt1 = "crt1.o";
8571*67e74705SXin Li     }
8572*67e74705SXin Li     if (crt1)
8573*67e74705SXin Li       CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crt1)));
8574*67e74705SXin Li 
8575*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o")));
8576*67e74705SXin Li 
8577*67e74705SXin Li     const char *crtbegin = nullptr;
8578*67e74705SXin Li     if (Args.hasArg(options::OPT_static))
8579*67e74705SXin Li       crtbegin = "crtbeginT.o";
8580*67e74705SXin Li     else if (Args.hasArg(options::OPT_shared) || IsPIE)
8581*67e74705SXin Li       crtbegin = "crtbeginS.o";
8582*67e74705SXin Li     else
8583*67e74705SXin Li       crtbegin = "crtbegin.o";
8584*67e74705SXin Li 
8585*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin)));
8586*67e74705SXin Li   }
8587*67e74705SXin Li 
8588*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_L);
8589*67e74705SXin Li   ToolChain.AddFilePathLibArgs(Args, CmdArgs);
8590*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
8591*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_e);
8592*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_s);
8593*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_t);
8594*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag);
8595*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_r);
8596*67e74705SXin Li 
8597*67e74705SXin Li   if (D.isUsingLTO())
8598*67e74705SXin Li     AddGoldPlugin(ToolChain, Args, CmdArgs, D.getLTOMode() == LTOK_Thin);
8599*67e74705SXin Li 
8600*67e74705SXin Li   bool NeedsSanitizerDeps = addSanitizerRuntimes(ToolChain, Args, CmdArgs);
8601*67e74705SXin Li   AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
8602*67e74705SXin Li 
8603*67e74705SXin Li   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
8604*67e74705SXin Li     addOpenMPRuntime(CmdArgs, ToolChain, Args);
8605*67e74705SXin Li     if (D.CCCIsCXX()) {
8606*67e74705SXin Li       ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
8607*67e74705SXin Li       if (Args.hasArg(options::OPT_pg))
8608*67e74705SXin Li         CmdArgs.push_back("-lm_p");
8609*67e74705SXin Li       else
8610*67e74705SXin Li         CmdArgs.push_back("-lm");
8611*67e74705SXin Li     }
8612*67e74705SXin Li     if (NeedsSanitizerDeps)
8613*67e74705SXin Li       linkSanitizerRuntimeDeps(ToolChain, CmdArgs);
8614*67e74705SXin Li     // FIXME: For some reason GCC passes -lgcc and -lgcc_s before adding
8615*67e74705SXin Li     // the default system libraries. Just mimic this for now.
8616*67e74705SXin Li     if (Args.hasArg(options::OPT_pg))
8617*67e74705SXin Li       CmdArgs.push_back("-lgcc_p");
8618*67e74705SXin Li     else
8619*67e74705SXin Li       CmdArgs.push_back("-lgcc");
8620*67e74705SXin Li     if (Args.hasArg(options::OPT_static)) {
8621*67e74705SXin Li       CmdArgs.push_back("-lgcc_eh");
8622*67e74705SXin Li     } else if (Args.hasArg(options::OPT_pg)) {
8623*67e74705SXin Li       CmdArgs.push_back("-lgcc_eh_p");
8624*67e74705SXin Li     } else {
8625*67e74705SXin Li       CmdArgs.push_back("--as-needed");
8626*67e74705SXin Li       CmdArgs.push_back("-lgcc_s");
8627*67e74705SXin Li       CmdArgs.push_back("--no-as-needed");
8628*67e74705SXin Li     }
8629*67e74705SXin Li 
8630*67e74705SXin Li     if (Args.hasArg(options::OPT_pthread)) {
8631*67e74705SXin Li       if (Args.hasArg(options::OPT_pg))
8632*67e74705SXin Li         CmdArgs.push_back("-lpthread_p");
8633*67e74705SXin Li       else
8634*67e74705SXin Li         CmdArgs.push_back("-lpthread");
8635*67e74705SXin Li     }
8636*67e74705SXin Li 
8637*67e74705SXin Li     if (Args.hasArg(options::OPT_pg)) {
8638*67e74705SXin Li       if (Args.hasArg(options::OPT_shared))
8639*67e74705SXin Li         CmdArgs.push_back("-lc");
8640*67e74705SXin Li       else
8641*67e74705SXin Li         CmdArgs.push_back("-lc_p");
8642*67e74705SXin Li       CmdArgs.push_back("-lgcc_p");
8643*67e74705SXin Li     } else {
8644*67e74705SXin Li       CmdArgs.push_back("-lc");
8645*67e74705SXin Li       CmdArgs.push_back("-lgcc");
8646*67e74705SXin Li     }
8647*67e74705SXin Li 
8648*67e74705SXin Li     if (Args.hasArg(options::OPT_static)) {
8649*67e74705SXin Li       CmdArgs.push_back("-lgcc_eh");
8650*67e74705SXin Li     } else if (Args.hasArg(options::OPT_pg)) {
8651*67e74705SXin Li       CmdArgs.push_back("-lgcc_eh_p");
8652*67e74705SXin Li     } else {
8653*67e74705SXin Li       CmdArgs.push_back("--as-needed");
8654*67e74705SXin Li       CmdArgs.push_back("-lgcc_s");
8655*67e74705SXin Li       CmdArgs.push_back("--no-as-needed");
8656*67e74705SXin Li     }
8657*67e74705SXin Li   }
8658*67e74705SXin Li 
8659*67e74705SXin Li   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
8660*67e74705SXin Li     if (Args.hasArg(options::OPT_shared) || IsPIE)
8661*67e74705SXin Li       CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtendS.o")));
8662*67e74705SXin Li     else
8663*67e74705SXin Li       CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtend.o")));
8664*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o")));
8665*67e74705SXin Li   }
8666*67e74705SXin Li 
8667*67e74705SXin Li   ToolChain.addProfileRTLibs(Args, CmdArgs);
8668*67e74705SXin Li 
8669*67e74705SXin Li   const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
8670*67e74705SXin Li   C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
8671*67e74705SXin Li }
8672*67e74705SXin Li 
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const8673*67e74705SXin Li void netbsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
8674*67e74705SXin Li                                      const InputInfo &Output,
8675*67e74705SXin Li                                      const InputInfoList &Inputs,
8676*67e74705SXin Li                                      const ArgList &Args,
8677*67e74705SXin Li                                      const char *LinkingOutput) const {
8678*67e74705SXin Li   claimNoWarnArgs(Args);
8679*67e74705SXin Li   ArgStringList CmdArgs;
8680*67e74705SXin Li 
8681*67e74705SXin Li   // GNU as needs different flags for creating the correct output format
8682*67e74705SXin Li   // on architectures with different ABIs or optional feature sets.
8683*67e74705SXin Li   switch (getToolChain().getArch()) {
8684*67e74705SXin Li   case llvm::Triple::x86:
8685*67e74705SXin Li     CmdArgs.push_back("--32");
8686*67e74705SXin Li     break;
8687*67e74705SXin Li   case llvm::Triple::arm:
8688*67e74705SXin Li   case llvm::Triple::armeb:
8689*67e74705SXin Li   case llvm::Triple::thumb:
8690*67e74705SXin Li   case llvm::Triple::thumbeb: {
8691*67e74705SXin Li     StringRef MArch, MCPU;
8692*67e74705SXin Li     getARMArchCPUFromArgs(Args, MArch, MCPU, /*FromAs*/ true);
8693*67e74705SXin Li     std::string Arch =
8694*67e74705SXin Li         arm::getARMTargetCPU(MCPU, MArch, getToolChain().getTriple());
8695*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString("-mcpu=" + Arch));
8696*67e74705SXin Li     break;
8697*67e74705SXin Li   }
8698*67e74705SXin Li 
8699*67e74705SXin Li   case llvm::Triple::mips:
8700*67e74705SXin Li   case llvm::Triple::mipsel:
8701*67e74705SXin Li   case llvm::Triple::mips64:
8702*67e74705SXin Li   case llvm::Triple::mips64el: {
8703*67e74705SXin Li     StringRef CPUName;
8704*67e74705SXin Li     StringRef ABIName;
8705*67e74705SXin Li     mips::getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName);
8706*67e74705SXin Li 
8707*67e74705SXin Li     CmdArgs.push_back("-march");
8708*67e74705SXin Li     CmdArgs.push_back(CPUName.data());
8709*67e74705SXin Li 
8710*67e74705SXin Li     CmdArgs.push_back("-mabi");
8711*67e74705SXin Li     CmdArgs.push_back(getGnuCompatibleMipsABIName(ABIName).data());
8712*67e74705SXin Li 
8713*67e74705SXin Li     if (getToolChain().getArch() == llvm::Triple::mips ||
8714*67e74705SXin Li         getToolChain().getArch() == llvm::Triple::mips64)
8715*67e74705SXin Li       CmdArgs.push_back("-EB");
8716*67e74705SXin Li     else
8717*67e74705SXin Li       CmdArgs.push_back("-EL");
8718*67e74705SXin Li 
8719*67e74705SXin Li     AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
8720*67e74705SXin Li     break;
8721*67e74705SXin Li   }
8722*67e74705SXin Li 
8723*67e74705SXin Li   case llvm::Triple::sparc:
8724*67e74705SXin Li   case llvm::Triple::sparcel: {
8725*67e74705SXin Li     CmdArgs.push_back("-32");
8726*67e74705SXin Li     std::string CPU = getCPUName(Args, getToolChain().getTriple());
8727*67e74705SXin Li     CmdArgs.push_back(getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
8728*67e74705SXin Li     AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
8729*67e74705SXin Li     break;
8730*67e74705SXin Li   }
8731*67e74705SXin Li 
8732*67e74705SXin Li   case llvm::Triple::sparcv9: {
8733*67e74705SXin Li     CmdArgs.push_back("-64");
8734*67e74705SXin Li     std::string CPU = getCPUName(Args, getToolChain().getTriple());
8735*67e74705SXin Li     CmdArgs.push_back(getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
8736*67e74705SXin Li     AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
8737*67e74705SXin Li     break;
8738*67e74705SXin Li   }
8739*67e74705SXin Li 
8740*67e74705SXin Li   default:
8741*67e74705SXin Li     break;
8742*67e74705SXin Li   }
8743*67e74705SXin Li 
8744*67e74705SXin Li   Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
8745*67e74705SXin Li 
8746*67e74705SXin Li   CmdArgs.push_back("-o");
8747*67e74705SXin Li   CmdArgs.push_back(Output.getFilename());
8748*67e74705SXin Li 
8749*67e74705SXin Li   for (const auto &II : Inputs)
8750*67e74705SXin Li     CmdArgs.push_back(II.getFilename());
8751*67e74705SXin Li 
8752*67e74705SXin Li   const char *Exec = Args.MakeArgString((getToolChain().GetProgramPath("as")));
8753*67e74705SXin Li   C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
8754*67e74705SXin Li }
8755*67e74705SXin Li 
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const8756*67e74705SXin Li void netbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
8757*67e74705SXin Li                                   const InputInfo &Output,
8758*67e74705SXin Li                                   const InputInfoList &Inputs,
8759*67e74705SXin Li                                   const ArgList &Args,
8760*67e74705SXin Li                                   const char *LinkingOutput) const {
8761*67e74705SXin Li   const Driver &D = getToolChain().getDriver();
8762*67e74705SXin Li   ArgStringList CmdArgs;
8763*67e74705SXin Li 
8764*67e74705SXin Li   if (!D.SysRoot.empty())
8765*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
8766*67e74705SXin Li 
8767*67e74705SXin Li   CmdArgs.push_back("--eh-frame-hdr");
8768*67e74705SXin Li   if (Args.hasArg(options::OPT_static)) {
8769*67e74705SXin Li     CmdArgs.push_back("-Bstatic");
8770*67e74705SXin Li   } else {
8771*67e74705SXin Li     if (Args.hasArg(options::OPT_rdynamic))
8772*67e74705SXin Li       CmdArgs.push_back("-export-dynamic");
8773*67e74705SXin Li     if (Args.hasArg(options::OPT_shared)) {
8774*67e74705SXin Li       CmdArgs.push_back("-Bshareable");
8775*67e74705SXin Li     } else {
8776*67e74705SXin Li       Args.AddAllArgs(CmdArgs, options::OPT_pie);
8777*67e74705SXin Li       CmdArgs.push_back("-dynamic-linker");
8778*67e74705SXin Li       CmdArgs.push_back("/libexec/ld.elf_so");
8779*67e74705SXin Li     }
8780*67e74705SXin Li   }
8781*67e74705SXin Li 
8782*67e74705SXin Li   // Many NetBSD architectures support more than one ABI.
8783*67e74705SXin Li   // Determine the correct emulation for ld.
8784*67e74705SXin Li   switch (getToolChain().getArch()) {
8785*67e74705SXin Li   case llvm::Triple::x86:
8786*67e74705SXin Li     CmdArgs.push_back("-m");
8787*67e74705SXin Li     CmdArgs.push_back("elf_i386");
8788*67e74705SXin Li     break;
8789*67e74705SXin Li   case llvm::Triple::arm:
8790*67e74705SXin Li   case llvm::Triple::thumb:
8791*67e74705SXin Li     CmdArgs.push_back("-m");
8792*67e74705SXin Li     switch (getToolChain().getTriple().getEnvironment()) {
8793*67e74705SXin Li     case llvm::Triple::EABI:
8794*67e74705SXin Li     case llvm::Triple::GNUEABI:
8795*67e74705SXin Li       CmdArgs.push_back("armelf_nbsd_eabi");
8796*67e74705SXin Li       break;
8797*67e74705SXin Li     case llvm::Triple::EABIHF:
8798*67e74705SXin Li     case llvm::Triple::GNUEABIHF:
8799*67e74705SXin Li       CmdArgs.push_back("armelf_nbsd_eabihf");
8800*67e74705SXin Li       break;
8801*67e74705SXin Li     default:
8802*67e74705SXin Li       CmdArgs.push_back("armelf_nbsd");
8803*67e74705SXin Li       break;
8804*67e74705SXin Li     }
8805*67e74705SXin Li     break;
8806*67e74705SXin Li   case llvm::Triple::armeb:
8807*67e74705SXin Li   case llvm::Triple::thumbeb:
8808*67e74705SXin Li     arm::appendEBLinkFlags(
8809*67e74705SXin Li         Args, CmdArgs,
8810*67e74705SXin Li         llvm::Triple(getToolChain().ComputeEffectiveClangTriple(Args)));
8811*67e74705SXin Li     CmdArgs.push_back("-m");
8812*67e74705SXin Li     switch (getToolChain().getTriple().getEnvironment()) {
8813*67e74705SXin Li     case llvm::Triple::EABI:
8814*67e74705SXin Li     case llvm::Triple::GNUEABI:
8815*67e74705SXin Li       CmdArgs.push_back("armelfb_nbsd_eabi");
8816*67e74705SXin Li       break;
8817*67e74705SXin Li     case llvm::Triple::EABIHF:
8818*67e74705SXin Li     case llvm::Triple::GNUEABIHF:
8819*67e74705SXin Li       CmdArgs.push_back("armelfb_nbsd_eabihf");
8820*67e74705SXin Li       break;
8821*67e74705SXin Li     default:
8822*67e74705SXin Li       CmdArgs.push_back("armelfb_nbsd");
8823*67e74705SXin Li       break;
8824*67e74705SXin Li     }
8825*67e74705SXin Li     break;
8826*67e74705SXin Li   case llvm::Triple::mips64:
8827*67e74705SXin Li   case llvm::Triple::mips64el:
8828*67e74705SXin Li     if (mips::hasMipsAbiArg(Args, "32")) {
8829*67e74705SXin Li       CmdArgs.push_back("-m");
8830*67e74705SXin Li       if (getToolChain().getArch() == llvm::Triple::mips64)
8831*67e74705SXin Li         CmdArgs.push_back("elf32btsmip");
8832*67e74705SXin Li       else
8833*67e74705SXin Li         CmdArgs.push_back("elf32ltsmip");
8834*67e74705SXin Li     } else if (mips::hasMipsAbiArg(Args, "64")) {
8835*67e74705SXin Li       CmdArgs.push_back("-m");
8836*67e74705SXin Li       if (getToolChain().getArch() == llvm::Triple::mips64)
8837*67e74705SXin Li         CmdArgs.push_back("elf64btsmip");
8838*67e74705SXin Li       else
8839*67e74705SXin Li         CmdArgs.push_back("elf64ltsmip");
8840*67e74705SXin Li     }
8841*67e74705SXin Li     break;
8842*67e74705SXin Li   case llvm::Triple::ppc:
8843*67e74705SXin Li     CmdArgs.push_back("-m");
8844*67e74705SXin Li     CmdArgs.push_back("elf32ppc_nbsd");
8845*67e74705SXin Li     break;
8846*67e74705SXin Li 
8847*67e74705SXin Li   case llvm::Triple::ppc64:
8848*67e74705SXin Li   case llvm::Triple::ppc64le:
8849*67e74705SXin Li     CmdArgs.push_back("-m");
8850*67e74705SXin Li     CmdArgs.push_back("elf64ppc");
8851*67e74705SXin Li     break;
8852*67e74705SXin Li 
8853*67e74705SXin Li   case llvm::Triple::sparc:
8854*67e74705SXin Li     CmdArgs.push_back("-m");
8855*67e74705SXin Li     CmdArgs.push_back("elf32_sparc");
8856*67e74705SXin Li     break;
8857*67e74705SXin Li 
8858*67e74705SXin Li   case llvm::Triple::sparcv9:
8859*67e74705SXin Li     CmdArgs.push_back("-m");
8860*67e74705SXin Li     CmdArgs.push_back("elf64_sparc");
8861*67e74705SXin Li     break;
8862*67e74705SXin Li 
8863*67e74705SXin Li   default:
8864*67e74705SXin Li     break;
8865*67e74705SXin Li   }
8866*67e74705SXin Li 
8867*67e74705SXin Li   if (Output.isFilename()) {
8868*67e74705SXin Li     CmdArgs.push_back("-o");
8869*67e74705SXin Li     CmdArgs.push_back(Output.getFilename());
8870*67e74705SXin Li   } else {
8871*67e74705SXin Li     assert(Output.isNothing() && "Invalid output.");
8872*67e74705SXin Li   }
8873*67e74705SXin Li 
8874*67e74705SXin Li   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
8875*67e74705SXin Li     if (!Args.hasArg(options::OPT_shared)) {
8876*67e74705SXin Li       CmdArgs.push_back(
8877*67e74705SXin Li           Args.MakeArgString(getToolChain().GetFilePath("crt0.o")));
8878*67e74705SXin Li     }
8879*67e74705SXin Li     CmdArgs.push_back(
8880*67e74705SXin Li         Args.MakeArgString(getToolChain().GetFilePath("crti.o")));
8881*67e74705SXin Li     if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie)) {
8882*67e74705SXin Li       CmdArgs.push_back(
8883*67e74705SXin Li           Args.MakeArgString(getToolChain().GetFilePath("crtbeginS.o")));
8884*67e74705SXin Li     } else {
8885*67e74705SXin Li       CmdArgs.push_back(
8886*67e74705SXin Li           Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o")));
8887*67e74705SXin Li     }
8888*67e74705SXin Li   }
8889*67e74705SXin Li 
8890*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_L);
8891*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
8892*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_e);
8893*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_s);
8894*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_t);
8895*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag);
8896*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_r);
8897*67e74705SXin Li 
8898*67e74705SXin Li   AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
8899*67e74705SXin Li 
8900*67e74705SXin Li   unsigned Major, Minor, Micro;
8901*67e74705SXin Li   getToolChain().getTriple().getOSVersion(Major, Minor, Micro);
8902*67e74705SXin Li   bool useLibgcc = true;
8903*67e74705SXin Li   if (Major >= 7 || Major == 0) {
8904*67e74705SXin Li     switch (getToolChain().getArch()) {
8905*67e74705SXin Li     case llvm::Triple::aarch64:
8906*67e74705SXin Li     case llvm::Triple::arm:
8907*67e74705SXin Li     case llvm::Triple::armeb:
8908*67e74705SXin Li     case llvm::Triple::thumb:
8909*67e74705SXin Li     case llvm::Triple::thumbeb:
8910*67e74705SXin Li     case llvm::Triple::ppc:
8911*67e74705SXin Li     case llvm::Triple::ppc64:
8912*67e74705SXin Li     case llvm::Triple::ppc64le:
8913*67e74705SXin Li     case llvm::Triple::sparc:
8914*67e74705SXin Li     case llvm::Triple::sparcv9:
8915*67e74705SXin Li     case llvm::Triple::x86:
8916*67e74705SXin Li     case llvm::Triple::x86_64:
8917*67e74705SXin Li       useLibgcc = false;
8918*67e74705SXin Li       break;
8919*67e74705SXin Li     default:
8920*67e74705SXin Li       break;
8921*67e74705SXin Li     }
8922*67e74705SXin Li   }
8923*67e74705SXin Li 
8924*67e74705SXin Li   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
8925*67e74705SXin Li     addOpenMPRuntime(CmdArgs, getToolChain(), Args);
8926*67e74705SXin Li     if (D.CCCIsCXX()) {
8927*67e74705SXin Li       getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
8928*67e74705SXin Li       CmdArgs.push_back("-lm");
8929*67e74705SXin Li     }
8930*67e74705SXin Li     if (Args.hasArg(options::OPT_pthread))
8931*67e74705SXin Li       CmdArgs.push_back("-lpthread");
8932*67e74705SXin Li     CmdArgs.push_back("-lc");
8933*67e74705SXin Li 
8934*67e74705SXin Li     if (useLibgcc) {
8935*67e74705SXin Li       if (Args.hasArg(options::OPT_static)) {
8936*67e74705SXin Li         // libgcc_eh depends on libc, so resolve as much as possible,
8937*67e74705SXin Li         // pull in any new requirements from libc and then get the rest
8938*67e74705SXin Li         // of libgcc.
8939*67e74705SXin Li         CmdArgs.push_back("-lgcc_eh");
8940*67e74705SXin Li         CmdArgs.push_back("-lc");
8941*67e74705SXin Li         CmdArgs.push_back("-lgcc");
8942*67e74705SXin Li       } else {
8943*67e74705SXin Li         CmdArgs.push_back("-lgcc");
8944*67e74705SXin Li         CmdArgs.push_back("--as-needed");
8945*67e74705SXin Li         CmdArgs.push_back("-lgcc_s");
8946*67e74705SXin Li         CmdArgs.push_back("--no-as-needed");
8947*67e74705SXin Li       }
8948*67e74705SXin Li     }
8949*67e74705SXin Li   }
8950*67e74705SXin Li 
8951*67e74705SXin Li   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
8952*67e74705SXin Li     if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
8953*67e74705SXin Li       CmdArgs.push_back(
8954*67e74705SXin Li           Args.MakeArgString(getToolChain().GetFilePath("crtendS.o")));
8955*67e74705SXin Li     else
8956*67e74705SXin Li       CmdArgs.push_back(
8957*67e74705SXin Li           Args.MakeArgString(getToolChain().GetFilePath("crtend.o")));
8958*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtn.o")));
8959*67e74705SXin Li   }
8960*67e74705SXin Li 
8961*67e74705SXin Li   getToolChain().addProfileRTLibs(Args, CmdArgs);
8962*67e74705SXin Li 
8963*67e74705SXin Li   const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
8964*67e74705SXin Li   C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
8965*67e74705SXin Li }
8966*67e74705SXin Li 
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const8967*67e74705SXin Li void gnutools::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
8968*67e74705SXin Li                                        const InputInfo &Output,
8969*67e74705SXin Li                                        const InputInfoList &Inputs,
8970*67e74705SXin Li                                        const ArgList &Args,
8971*67e74705SXin Li                                        const char *LinkingOutput) const {
8972*67e74705SXin Li   claimNoWarnArgs(Args);
8973*67e74705SXin Li 
8974*67e74705SXin Li   std::string TripleStr = getToolChain().ComputeEffectiveClangTriple(Args);
8975*67e74705SXin Li   llvm::Triple Triple = llvm::Triple(TripleStr);
8976*67e74705SXin Li 
8977*67e74705SXin Li   ArgStringList CmdArgs;
8978*67e74705SXin Li 
8979*67e74705SXin Li   llvm::Reloc::Model RelocationModel;
8980*67e74705SXin Li   unsigned PICLevel;
8981*67e74705SXin Li   bool IsPIE;
8982*67e74705SXin Li   std::tie(RelocationModel, PICLevel, IsPIE) =
8983*67e74705SXin Li       ParsePICArgs(getToolChain(), Triple, Args);
8984*67e74705SXin Li 
8985*67e74705SXin Li   switch (getToolChain().getArch()) {
8986*67e74705SXin Li   default:
8987*67e74705SXin Li     break;
8988*67e74705SXin Li   // Add --32/--64 to make sure we get the format we want.
8989*67e74705SXin Li   // This is incomplete
8990*67e74705SXin Li   case llvm::Triple::x86:
8991*67e74705SXin Li     CmdArgs.push_back("--32");
8992*67e74705SXin Li     break;
8993*67e74705SXin Li   case llvm::Triple::x86_64:
8994*67e74705SXin Li     if (getToolChain().getTriple().getEnvironment() == llvm::Triple::GNUX32)
8995*67e74705SXin Li       CmdArgs.push_back("--x32");
8996*67e74705SXin Li     else
8997*67e74705SXin Li       CmdArgs.push_back("--64");
8998*67e74705SXin Li     break;
8999*67e74705SXin Li   case llvm::Triple::ppc:
9000*67e74705SXin Li     CmdArgs.push_back("-a32");
9001*67e74705SXin Li     CmdArgs.push_back("-mppc");
9002*67e74705SXin Li     CmdArgs.push_back("-many");
9003*67e74705SXin Li     break;
9004*67e74705SXin Li   case llvm::Triple::ppc64:
9005*67e74705SXin Li     CmdArgs.push_back("-a64");
9006*67e74705SXin Li     CmdArgs.push_back("-mppc64");
9007*67e74705SXin Li     CmdArgs.push_back("-many");
9008*67e74705SXin Li     break;
9009*67e74705SXin Li   case llvm::Triple::ppc64le:
9010*67e74705SXin Li     CmdArgs.push_back("-a64");
9011*67e74705SXin Li     CmdArgs.push_back("-mppc64");
9012*67e74705SXin Li     CmdArgs.push_back("-many");
9013*67e74705SXin Li     CmdArgs.push_back("-mlittle-endian");
9014*67e74705SXin Li     break;
9015*67e74705SXin Li   case llvm::Triple::sparc:
9016*67e74705SXin Li   case llvm::Triple::sparcel: {
9017*67e74705SXin Li     CmdArgs.push_back("-32");
9018*67e74705SXin Li     std::string CPU = getCPUName(Args, getToolChain().getTriple());
9019*67e74705SXin Li     CmdArgs.push_back(getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
9020*67e74705SXin Li     AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
9021*67e74705SXin Li     break;
9022*67e74705SXin Li   }
9023*67e74705SXin Li   case llvm::Triple::sparcv9: {
9024*67e74705SXin Li     CmdArgs.push_back("-64");
9025*67e74705SXin Li     std::string CPU = getCPUName(Args, getToolChain().getTriple());
9026*67e74705SXin Li     CmdArgs.push_back(getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
9027*67e74705SXin Li     AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
9028*67e74705SXin Li     break;
9029*67e74705SXin Li   }
9030*67e74705SXin Li   case llvm::Triple::arm:
9031*67e74705SXin Li   case llvm::Triple::armeb:
9032*67e74705SXin Li   case llvm::Triple::thumb:
9033*67e74705SXin Li   case llvm::Triple::thumbeb: {
9034*67e74705SXin Li     const llvm::Triple &Triple2 = getToolChain().getTriple();
9035*67e74705SXin Li     switch (Triple2.getSubArch()) {
9036*67e74705SXin Li     case llvm::Triple::ARMSubArch_v7:
9037*67e74705SXin Li       CmdArgs.push_back("-mfpu=neon");
9038*67e74705SXin Li       break;
9039*67e74705SXin Li     case llvm::Triple::ARMSubArch_v8:
9040*67e74705SXin Li       CmdArgs.push_back("-mfpu=crypto-neon-fp-armv8");
9041*67e74705SXin Li       break;
9042*67e74705SXin Li     default:
9043*67e74705SXin Li       break;
9044*67e74705SXin Li     }
9045*67e74705SXin Li 
9046*67e74705SXin Li     switch (arm::getARMFloatABI(getToolChain(), Args)) {
9047*67e74705SXin Li     case arm::FloatABI::Invalid: llvm_unreachable("must have an ABI!");
9048*67e74705SXin Li     case arm::FloatABI::Soft:
9049*67e74705SXin Li       CmdArgs.push_back(Args.MakeArgString("-mfloat-abi=soft"));
9050*67e74705SXin Li       break;
9051*67e74705SXin Li     case arm::FloatABI::SoftFP:
9052*67e74705SXin Li       CmdArgs.push_back(Args.MakeArgString("-mfloat-abi=softfp"));
9053*67e74705SXin Li       break;
9054*67e74705SXin Li     case arm::FloatABI::Hard:
9055*67e74705SXin Li       CmdArgs.push_back(Args.MakeArgString("-mfloat-abi=hard"));
9056*67e74705SXin Li       break;
9057*67e74705SXin Li     }
9058*67e74705SXin Li 
9059*67e74705SXin Li     Args.AddLastArg(CmdArgs, options::OPT_march_EQ);
9060*67e74705SXin Li 
9061*67e74705SXin Li     // FIXME: remove krait check when GNU tools support krait cpu
9062*67e74705SXin Li     // for now replace it with -mcpu=cortex-a15 to avoid a lower
9063*67e74705SXin Li     // march from being picked in the absence of a cpu flag.
9064*67e74705SXin Li     Arg *A;
9065*67e74705SXin Li     if ((A = Args.getLastArg(options::OPT_mcpu_EQ)) &&
9066*67e74705SXin Li         StringRef(A->getValue()).lower() == "krait")
9067*67e74705SXin Li       CmdArgs.push_back("-mcpu=cortex-a15");
9068*67e74705SXin Li     else
9069*67e74705SXin Li       Args.AddLastArg(CmdArgs, options::OPT_mcpu_EQ);
9070*67e74705SXin Li     Args.AddLastArg(CmdArgs, options::OPT_mfpu_EQ);
9071*67e74705SXin Li     break;
9072*67e74705SXin Li   }
9073*67e74705SXin Li   case llvm::Triple::mips:
9074*67e74705SXin Li   case llvm::Triple::mipsel:
9075*67e74705SXin Li   case llvm::Triple::mips64:
9076*67e74705SXin Li   case llvm::Triple::mips64el: {
9077*67e74705SXin Li     StringRef CPUName;
9078*67e74705SXin Li     StringRef ABIName;
9079*67e74705SXin Li     mips::getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName);
9080*67e74705SXin Li     ABIName = getGnuCompatibleMipsABIName(ABIName);
9081*67e74705SXin Li 
9082*67e74705SXin Li     CmdArgs.push_back("-march");
9083*67e74705SXin Li     CmdArgs.push_back(CPUName.data());
9084*67e74705SXin Li 
9085*67e74705SXin Li     CmdArgs.push_back("-mabi");
9086*67e74705SXin Li     CmdArgs.push_back(ABIName.data());
9087*67e74705SXin Li 
9088*67e74705SXin Li     // -mno-shared should be emitted unless -fpic, -fpie, -fPIC, -fPIE,
9089*67e74705SXin Li     // or -mshared (not implemented) is in effect.
9090*67e74705SXin Li     if (RelocationModel == llvm::Reloc::Static)
9091*67e74705SXin Li       CmdArgs.push_back("-mno-shared");
9092*67e74705SXin Li 
9093*67e74705SXin Li     // LLVM doesn't support -mplt yet and acts as if it is always given.
9094*67e74705SXin Li     // However, -mplt has no effect with the N64 ABI.
9095*67e74705SXin Li     CmdArgs.push_back(ABIName == "64" ? "-KPIC" : "-call_nonpic");
9096*67e74705SXin Li 
9097*67e74705SXin Li     if (getToolChain().getArch() == llvm::Triple::mips ||
9098*67e74705SXin Li         getToolChain().getArch() == llvm::Triple::mips64)
9099*67e74705SXin Li       CmdArgs.push_back("-EB");
9100*67e74705SXin Li     else
9101*67e74705SXin Li       CmdArgs.push_back("-EL");
9102*67e74705SXin Li 
9103*67e74705SXin Li     if (Arg *A = Args.getLastArg(options::OPT_mnan_EQ)) {
9104*67e74705SXin Li       if (StringRef(A->getValue()) == "2008")
9105*67e74705SXin Li         CmdArgs.push_back(Args.MakeArgString("-mnan=2008"));
9106*67e74705SXin Li     }
9107*67e74705SXin Li 
9108*67e74705SXin Li     // Add the last -mfp32/-mfpxx/-mfp64 or -mfpxx if it is enabled by default.
9109*67e74705SXin Li     if (Arg *A = Args.getLastArg(options::OPT_mfp32, options::OPT_mfpxx,
9110*67e74705SXin Li                                  options::OPT_mfp64)) {
9111*67e74705SXin Li       A->claim();
9112*67e74705SXin Li       A->render(Args, CmdArgs);
9113*67e74705SXin Li     } else if (mips::shouldUseFPXX(
9114*67e74705SXin Li                    Args, getToolChain().getTriple(), CPUName, ABIName,
9115*67e74705SXin Li                    getMipsFloatABI(getToolChain().getDriver(), Args)))
9116*67e74705SXin Li       CmdArgs.push_back("-mfpxx");
9117*67e74705SXin Li 
9118*67e74705SXin Li     // Pass on -mmips16 or -mno-mips16. However, the assembler equivalent of
9119*67e74705SXin Li     // -mno-mips16 is actually -no-mips16.
9120*67e74705SXin Li     if (Arg *A =
9121*67e74705SXin Li             Args.getLastArg(options::OPT_mips16, options::OPT_mno_mips16)) {
9122*67e74705SXin Li       if (A->getOption().matches(options::OPT_mips16)) {
9123*67e74705SXin Li         A->claim();
9124*67e74705SXin Li         A->render(Args, CmdArgs);
9125*67e74705SXin Li       } else {
9126*67e74705SXin Li         A->claim();
9127*67e74705SXin Li         CmdArgs.push_back("-no-mips16");
9128*67e74705SXin Li       }
9129*67e74705SXin Li     }
9130*67e74705SXin Li 
9131*67e74705SXin Li     Args.AddLastArg(CmdArgs, options::OPT_mmicromips,
9132*67e74705SXin Li                     options::OPT_mno_micromips);
9133*67e74705SXin Li     Args.AddLastArg(CmdArgs, options::OPT_mdsp, options::OPT_mno_dsp);
9134*67e74705SXin Li     Args.AddLastArg(CmdArgs, options::OPT_mdspr2, options::OPT_mno_dspr2);
9135*67e74705SXin Li 
9136*67e74705SXin Li     if (Arg *A = Args.getLastArg(options::OPT_mmsa, options::OPT_mno_msa)) {
9137*67e74705SXin Li       // Do not use AddLastArg because not all versions of MIPS assembler
9138*67e74705SXin Li       // support -mmsa / -mno-msa options.
9139*67e74705SXin Li       if (A->getOption().matches(options::OPT_mmsa))
9140*67e74705SXin Li         CmdArgs.push_back(Args.MakeArgString("-mmsa"));
9141*67e74705SXin Li     }
9142*67e74705SXin Li 
9143*67e74705SXin Li     Args.AddLastArg(CmdArgs, options::OPT_mhard_float,
9144*67e74705SXin Li                     options::OPT_msoft_float);
9145*67e74705SXin Li 
9146*67e74705SXin Li     Args.AddLastArg(CmdArgs, options::OPT_mdouble_float,
9147*67e74705SXin Li                     options::OPT_msingle_float);
9148*67e74705SXin Li 
9149*67e74705SXin Li     Args.AddLastArg(CmdArgs, options::OPT_modd_spreg,
9150*67e74705SXin Li                     options::OPT_mno_odd_spreg);
9151*67e74705SXin Li 
9152*67e74705SXin Li     AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
9153*67e74705SXin Li     break;
9154*67e74705SXin Li   }
9155*67e74705SXin Li   case llvm::Triple::systemz: {
9156*67e74705SXin Li     // Always pass an -march option, since our default of z10 is later
9157*67e74705SXin Li     // than the GNU assembler's default.
9158*67e74705SXin Li     StringRef CPUName = getSystemZTargetCPU(Args);
9159*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString("-march=" + CPUName));
9160*67e74705SXin Li     break;
9161*67e74705SXin Li   }
9162*67e74705SXin Li   }
9163*67e74705SXin Li 
9164*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_I);
9165*67e74705SXin Li   Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
9166*67e74705SXin Li 
9167*67e74705SXin Li   CmdArgs.push_back("-o");
9168*67e74705SXin Li   CmdArgs.push_back(Output.getFilename());
9169*67e74705SXin Li 
9170*67e74705SXin Li   for (const auto &II : Inputs)
9171*67e74705SXin Li     CmdArgs.push_back(II.getFilename());
9172*67e74705SXin Li 
9173*67e74705SXin Li   const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
9174*67e74705SXin Li   C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
9175*67e74705SXin Li 
9176*67e74705SXin Li   // Handle the debug info splitting at object creation time if we're
9177*67e74705SXin Li   // creating an object.
9178*67e74705SXin Li   // TODO: Currently only works on linux with newer objcopy.
9179*67e74705SXin Li   if (Args.hasArg(options::OPT_gsplit_dwarf) &&
9180*67e74705SXin Li       getToolChain().getTriple().isOSLinux())
9181*67e74705SXin Li     SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output,
9182*67e74705SXin Li                    SplitDebugName(Args, Inputs[0]));
9183*67e74705SXin Li }
9184*67e74705SXin Li 
AddLibgcc(const llvm::Triple & Triple,const Driver & D,ArgStringList & CmdArgs,const ArgList & Args)9185*67e74705SXin Li static void AddLibgcc(const llvm::Triple &Triple, const Driver &D,
9186*67e74705SXin Li                       ArgStringList &CmdArgs, const ArgList &Args) {
9187*67e74705SXin Li   bool isAndroid = Triple.isAndroid();
9188*67e74705SXin Li   bool isCygMing = Triple.isOSCygMing();
9189*67e74705SXin Li   bool IsIAMCU = Triple.isOSIAMCU();
9190*67e74705SXin Li   bool StaticLibgcc = Args.hasArg(options::OPT_static_libgcc) ||
9191*67e74705SXin Li                       Args.hasArg(options::OPT_static);
9192*67e74705SXin Li   if (!D.CCCIsCXX())
9193*67e74705SXin Li     CmdArgs.push_back("-lgcc");
9194*67e74705SXin Li 
9195*67e74705SXin Li   if (StaticLibgcc || isAndroid) {
9196*67e74705SXin Li     if (D.CCCIsCXX())
9197*67e74705SXin Li       CmdArgs.push_back("-lgcc");
9198*67e74705SXin Li   } else {
9199*67e74705SXin Li     if (!D.CCCIsCXX() && !isCygMing)
9200*67e74705SXin Li       CmdArgs.push_back("--as-needed");
9201*67e74705SXin Li     CmdArgs.push_back("-lgcc_s");
9202*67e74705SXin Li     if (!D.CCCIsCXX() && !isCygMing)
9203*67e74705SXin Li       CmdArgs.push_back("--no-as-needed");
9204*67e74705SXin Li   }
9205*67e74705SXin Li 
9206*67e74705SXin Li   if (StaticLibgcc && !isAndroid && !IsIAMCU)
9207*67e74705SXin Li     CmdArgs.push_back("-lgcc_eh");
9208*67e74705SXin Li   else if (!Args.hasArg(options::OPT_shared) && D.CCCIsCXX())
9209*67e74705SXin Li     CmdArgs.push_back("-lgcc");
9210*67e74705SXin Li 
9211*67e74705SXin Li   // According to Android ABI, we have to link with libdl if we are
9212*67e74705SXin Li   // linking with non-static libgcc.
9213*67e74705SXin Li   //
9214*67e74705SXin Li   // NOTE: This fixes a link error on Android MIPS as well.  The non-static
9215*67e74705SXin Li   // libgcc for MIPS relies on _Unwind_Find_FDE and dl_iterate_phdr from libdl.
9216*67e74705SXin Li   if (isAndroid && !StaticLibgcc)
9217*67e74705SXin Li     CmdArgs.push_back("-ldl");
9218*67e74705SXin Li }
9219*67e74705SXin Li 
AddRunTimeLibs(const ToolChain & TC,const Driver & D,ArgStringList & CmdArgs,const ArgList & Args)9220*67e74705SXin Li static void AddRunTimeLibs(const ToolChain &TC, const Driver &D,
9221*67e74705SXin Li                            ArgStringList &CmdArgs, const ArgList &Args) {
9222*67e74705SXin Li   // Make use of compiler-rt if --rtlib option is used
9223*67e74705SXin Li   ToolChain::RuntimeLibType RLT = TC.GetRuntimeLibType(Args);
9224*67e74705SXin Li 
9225*67e74705SXin Li   switch (RLT) {
9226*67e74705SXin Li   case ToolChain::RLT_CompilerRT:
9227*67e74705SXin Li     switch (TC.getTriple().getOS()) {
9228*67e74705SXin Li     default:
9229*67e74705SXin Li       llvm_unreachable("unsupported OS");
9230*67e74705SXin Li     case llvm::Triple::Win32:
9231*67e74705SXin Li     case llvm::Triple::Linux:
9232*67e74705SXin Li       addClangRT(TC, Args, CmdArgs);
9233*67e74705SXin Li       break;
9234*67e74705SXin Li     }
9235*67e74705SXin Li     break;
9236*67e74705SXin Li   case ToolChain::RLT_Libgcc:
9237*67e74705SXin Li     // Make sure libgcc is not used under MSVC environment by default
9238*67e74705SXin Li     if (TC.getTriple().isKnownWindowsMSVCEnvironment()) {
9239*67e74705SXin Li       // Issue error diagnostic if libgcc is explicitly specified
9240*67e74705SXin Li       // through command line as --rtlib option argument.
9241*67e74705SXin Li       if (Args.hasArg(options::OPT_rtlib_EQ)) {
9242*67e74705SXin Li         TC.getDriver().Diag(diag::err_drv_unsupported_rtlib_for_platform)
9243*67e74705SXin Li             << Args.getLastArg(options::OPT_rtlib_EQ)->getValue() << "MSVC";
9244*67e74705SXin Li       }
9245*67e74705SXin Li     } else
9246*67e74705SXin Li       AddLibgcc(TC.getTriple(), D, CmdArgs, Args);
9247*67e74705SXin Li     break;
9248*67e74705SXin Li   }
9249*67e74705SXin Li }
9250*67e74705SXin Li 
getLDMOption(const llvm::Triple & T,const ArgList & Args)9251*67e74705SXin Li static const char *getLDMOption(const llvm::Triple &T, const ArgList &Args) {
9252*67e74705SXin Li   switch (T.getArch()) {
9253*67e74705SXin Li   case llvm::Triple::x86:
9254*67e74705SXin Li     if (T.isOSIAMCU())
9255*67e74705SXin Li       return "elf_iamcu";
9256*67e74705SXin Li     return "elf_i386";
9257*67e74705SXin Li   case llvm::Triple::aarch64:
9258*67e74705SXin Li     return "aarch64linux";
9259*67e74705SXin Li   case llvm::Triple::aarch64_be:
9260*67e74705SXin Li     return "aarch64_be_linux";
9261*67e74705SXin Li   case llvm::Triple::arm:
9262*67e74705SXin Li   case llvm::Triple::thumb:
9263*67e74705SXin Li     return "armelf_linux_eabi";
9264*67e74705SXin Li   case llvm::Triple::armeb:
9265*67e74705SXin Li   case llvm::Triple::thumbeb:
9266*67e74705SXin Li     return "armelfb_linux_eabi";
9267*67e74705SXin Li   case llvm::Triple::ppc:
9268*67e74705SXin Li     return "elf32ppclinux";
9269*67e74705SXin Li   case llvm::Triple::ppc64:
9270*67e74705SXin Li     return "elf64ppc";
9271*67e74705SXin Li   case llvm::Triple::ppc64le:
9272*67e74705SXin Li     return "elf64lppc";
9273*67e74705SXin Li   case llvm::Triple::sparc:
9274*67e74705SXin Li   case llvm::Triple::sparcel:
9275*67e74705SXin Li     return "elf32_sparc";
9276*67e74705SXin Li   case llvm::Triple::sparcv9:
9277*67e74705SXin Li     return "elf64_sparc";
9278*67e74705SXin Li   case llvm::Triple::mips:
9279*67e74705SXin Li     return "elf32btsmip";
9280*67e74705SXin Li   case llvm::Triple::mipsel:
9281*67e74705SXin Li     return "elf32ltsmip";
9282*67e74705SXin Li   case llvm::Triple::mips64:
9283*67e74705SXin Li     if (mips::hasMipsAbiArg(Args, "n32"))
9284*67e74705SXin Li       return "elf32btsmipn32";
9285*67e74705SXin Li     return "elf64btsmip";
9286*67e74705SXin Li   case llvm::Triple::mips64el:
9287*67e74705SXin Li     if (mips::hasMipsAbiArg(Args, "n32"))
9288*67e74705SXin Li       return "elf32ltsmipn32";
9289*67e74705SXin Li     return "elf64ltsmip";
9290*67e74705SXin Li   case llvm::Triple::systemz:
9291*67e74705SXin Li     return "elf64_s390";
9292*67e74705SXin Li   case llvm::Triple::x86_64:
9293*67e74705SXin Li     if (T.getEnvironment() == llvm::Triple::GNUX32)
9294*67e74705SXin Li       return "elf32_x86_64";
9295*67e74705SXin Li     return "elf_x86_64";
9296*67e74705SXin Li   default:
9297*67e74705SXin Li     llvm_unreachable("Unexpected arch");
9298*67e74705SXin Li   }
9299*67e74705SXin Li }
9300*67e74705SXin Li 
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const9301*67e74705SXin Li void gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
9302*67e74705SXin Li                                     const InputInfo &Output,
9303*67e74705SXin Li                                     const InputInfoList &Inputs,
9304*67e74705SXin Li                                     const ArgList &Args,
9305*67e74705SXin Li                                     const char *LinkingOutput) const {
9306*67e74705SXin Li   const toolchains::Linux &ToolChain =
9307*67e74705SXin Li       static_cast<const toolchains::Linux &>(getToolChain());
9308*67e74705SXin Li   const Driver &D = ToolChain.getDriver();
9309*67e74705SXin Li 
9310*67e74705SXin Li   std::string TripleStr = getToolChain().ComputeEffectiveClangTriple(Args);
9311*67e74705SXin Li   llvm::Triple Triple = llvm::Triple(TripleStr);
9312*67e74705SXin Li 
9313*67e74705SXin Li   const llvm::Triple::ArchType Arch = ToolChain.getArch();
9314*67e74705SXin Li   const bool isAndroid = ToolChain.getTriple().isAndroid();
9315*67e74705SXin Li   const bool IsIAMCU = ToolChain.getTriple().isOSIAMCU();
9316*67e74705SXin Li   const bool IsPIE =
9317*67e74705SXin Li       !Args.hasArg(options::OPT_shared) && !Args.hasArg(options::OPT_static) &&
9318*67e74705SXin Li       (Args.hasArg(options::OPT_pie) || ToolChain.isPIEDefault());
9319*67e74705SXin Li   const bool HasCRTBeginEndFiles =
9320*67e74705SXin Li       ToolChain.getTriple().hasEnvironment() ||
9321*67e74705SXin Li       (ToolChain.getTriple().getVendor() != llvm::Triple::MipsTechnologies);
9322*67e74705SXin Li 
9323*67e74705SXin Li   ArgStringList CmdArgs;
9324*67e74705SXin Li 
9325*67e74705SXin Li   // Silence warning for "clang -g foo.o -o foo"
9326*67e74705SXin Li   Args.ClaimAllArgs(options::OPT_g_Group);
9327*67e74705SXin Li   // and "clang -emit-llvm foo.o -o foo"
9328*67e74705SXin Li   Args.ClaimAllArgs(options::OPT_emit_llvm);
9329*67e74705SXin Li   // and for "clang -w foo.o -o foo". Other warning options are already
9330*67e74705SXin Li   // handled somewhere else.
9331*67e74705SXin Li   Args.ClaimAllArgs(options::OPT_w);
9332*67e74705SXin Li 
9333*67e74705SXin Li   const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath());
9334*67e74705SXin Li   if (llvm::sys::path::filename(Exec) == "lld") {
9335*67e74705SXin Li     CmdArgs.push_back("-flavor");
9336*67e74705SXin Li     CmdArgs.push_back("old-gnu");
9337*67e74705SXin Li     CmdArgs.push_back("-target");
9338*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(getToolChain().getTripleString()));
9339*67e74705SXin Li   }
9340*67e74705SXin Li 
9341*67e74705SXin Li   if (!D.SysRoot.empty())
9342*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
9343*67e74705SXin Li 
9344*67e74705SXin Li   if (IsPIE)
9345*67e74705SXin Li     CmdArgs.push_back("-pie");
9346*67e74705SXin Li 
9347*67e74705SXin Li   if (Args.hasArg(options::OPT_rdynamic))
9348*67e74705SXin Li     CmdArgs.push_back("-export-dynamic");
9349*67e74705SXin Li 
9350*67e74705SXin Li   if (Args.hasArg(options::OPT_s))
9351*67e74705SXin Li     CmdArgs.push_back("-s");
9352*67e74705SXin Li 
9353*67e74705SXin Li   if (Arch == llvm::Triple::armeb || Arch == llvm::Triple::thumbeb)
9354*67e74705SXin Li     arm::appendEBLinkFlags(Args, CmdArgs, Triple);
9355*67e74705SXin Li 
9356*67e74705SXin Li   for (const auto &Opt : ToolChain.ExtraOpts)
9357*67e74705SXin Li     CmdArgs.push_back(Opt.c_str());
9358*67e74705SXin Li 
9359*67e74705SXin Li   if (!Args.hasArg(options::OPT_static)) {
9360*67e74705SXin Li     CmdArgs.push_back("--eh-frame-hdr");
9361*67e74705SXin Li   }
9362*67e74705SXin Li 
9363*67e74705SXin Li   CmdArgs.push_back("-m");
9364*67e74705SXin Li   CmdArgs.push_back(getLDMOption(ToolChain.getTriple(), Args));
9365*67e74705SXin Li 
9366*67e74705SXin Li   if (Args.hasArg(options::OPT_static)) {
9367*67e74705SXin Li     if (Arch == llvm::Triple::arm || Arch == llvm::Triple::armeb ||
9368*67e74705SXin Li         Arch == llvm::Triple::thumb || Arch == llvm::Triple::thumbeb)
9369*67e74705SXin Li       CmdArgs.push_back("-Bstatic");
9370*67e74705SXin Li     else
9371*67e74705SXin Li       CmdArgs.push_back("-static");
9372*67e74705SXin Li   } else if (Args.hasArg(options::OPT_shared)) {
9373*67e74705SXin Li     CmdArgs.push_back("-shared");
9374*67e74705SXin Li   }
9375*67e74705SXin Li 
9376*67e74705SXin Li   if (!Args.hasArg(options::OPT_static)) {
9377*67e74705SXin Li     if (Args.hasArg(options::OPT_rdynamic))
9378*67e74705SXin Li       CmdArgs.push_back("-export-dynamic");
9379*67e74705SXin Li 
9380*67e74705SXin Li     if (!Args.hasArg(options::OPT_shared)) {
9381*67e74705SXin Li       const std::string Loader =
9382*67e74705SXin Li           D.DyldPrefix + ToolChain.getDynamicLinker(Args);
9383*67e74705SXin Li       CmdArgs.push_back("-dynamic-linker");
9384*67e74705SXin Li       CmdArgs.push_back(Args.MakeArgString(Loader));
9385*67e74705SXin Li     }
9386*67e74705SXin Li   }
9387*67e74705SXin Li 
9388*67e74705SXin Li   CmdArgs.push_back("-o");
9389*67e74705SXin Li   CmdArgs.push_back(Output.getFilename());
9390*67e74705SXin Li 
9391*67e74705SXin Li   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
9392*67e74705SXin Li     if (!isAndroid && !IsIAMCU) {
9393*67e74705SXin Li       const char *crt1 = nullptr;
9394*67e74705SXin Li       if (!Args.hasArg(options::OPT_shared)) {
9395*67e74705SXin Li         if (Args.hasArg(options::OPT_pg))
9396*67e74705SXin Li           crt1 = "gcrt1.o";
9397*67e74705SXin Li         else if (IsPIE)
9398*67e74705SXin Li           crt1 = "Scrt1.o";
9399*67e74705SXin Li         else
9400*67e74705SXin Li           crt1 = "crt1.o";
9401*67e74705SXin Li       }
9402*67e74705SXin Li       if (crt1)
9403*67e74705SXin Li         CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crt1)));
9404*67e74705SXin Li 
9405*67e74705SXin Li       CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o")));
9406*67e74705SXin Li     }
9407*67e74705SXin Li 
9408*67e74705SXin Li     if (IsIAMCU)
9409*67e74705SXin Li       CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crt0.o")));
9410*67e74705SXin Li     else {
9411*67e74705SXin Li       const char *crtbegin;
9412*67e74705SXin Li       if (Args.hasArg(options::OPT_static))
9413*67e74705SXin Li         crtbegin = isAndroid ? "crtbegin_static.o" : "crtbeginT.o";
9414*67e74705SXin Li       else if (Args.hasArg(options::OPT_shared))
9415*67e74705SXin Li         crtbegin = isAndroid ? "crtbegin_so.o" : "crtbeginS.o";
9416*67e74705SXin Li       else if (IsPIE)
9417*67e74705SXin Li         crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbeginS.o";
9418*67e74705SXin Li       else
9419*67e74705SXin Li         crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbegin.o";
9420*67e74705SXin Li 
9421*67e74705SXin Li       if (HasCRTBeginEndFiles)
9422*67e74705SXin Li         CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin)));
9423*67e74705SXin Li     }
9424*67e74705SXin Li 
9425*67e74705SXin Li     // Add crtfastmath.o if available and fast math is enabled.
9426*67e74705SXin Li     ToolChain.AddFastMathRuntimeIfAvailable(Args, CmdArgs);
9427*67e74705SXin Li   }
9428*67e74705SXin Li 
9429*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_L);
9430*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_u);
9431*67e74705SXin Li 
9432*67e74705SXin Li   ToolChain.AddFilePathLibArgs(Args, CmdArgs);
9433*67e74705SXin Li 
9434*67e74705SXin Li   if (D.isUsingLTO())
9435*67e74705SXin Li     AddGoldPlugin(ToolChain, Args, CmdArgs, D.getLTOMode() == LTOK_Thin);
9436*67e74705SXin Li 
9437*67e74705SXin Li   if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
9438*67e74705SXin Li     CmdArgs.push_back("--no-demangle");
9439*67e74705SXin Li 
9440*67e74705SXin Li   bool NeedsSanitizerDeps = addSanitizerRuntimes(ToolChain, Args, CmdArgs);
9441*67e74705SXin Li   bool NeedsXRayDeps = addXRayRuntime(ToolChain, Args, CmdArgs);
9442*67e74705SXin Li   AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
9443*67e74705SXin Li   // The profile runtime also needs access to system libraries.
9444*67e74705SXin Li   getToolChain().addProfileRTLibs(Args, CmdArgs);
9445*67e74705SXin Li 
9446*67e74705SXin Li   if (D.CCCIsCXX() &&
9447*67e74705SXin Li       !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
9448*67e74705SXin Li     bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
9449*67e74705SXin Li                                !Args.hasArg(options::OPT_static);
9450*67e74705SXin Li     if (OnlyLibstdcxxStatic)
9451*67e74705SXin Li       CmdArgs.push_back("-Bstatic");
9452*67e74705SXin Li     ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
9453*67e74705SXin Li     if (OnlyLibstdcxxStatic)
9454*67e74705SXin Li       CmdArgs.push_back("-Bdynamic");
9455*67e74705SXin Li     CmdArgs.push_back("-lm");
9456*67e74705SXin Li   }
9457*67e74705SXin Li   // Silence warnings when linking C code with a C++ '-stdlib' argument.
9458*67e74705SXin Li   Args.ClaimAllArgs(options::OPT_stdlib_EQ);
9459*67e74705SXin Li 
9460*67e74705SXin Li   if (!Args.hasArg(options::OPT_nostdlib)) {
9461*67e74705SXin Li     if (!Args.hasArg(options::OPT_nodefaultlibs)) {
9462*67e74705SXin Li       if (Args.hasArg(options::OPT_static))
9463*67e74705SXin Li         CmdArgs.push_back("--start-group");
9464*67e74705SXin Li 
9465*67e74705SXin Li       if (NeedsSanitizerDeps)
9466*67e74705SXin Li         linkSanitizerRuntimeDeps(ToolChain, CmdArgs);
9467*67e74705SXin Li 
9468*67e74705SXin Li       if (NeedsXRayDeps)
9469*67e74705SXin Li         linkXRayRuntimeDeps(ToolChain, Args, CmdArgs);
9470*67e74705SXin Li 
9471*67e74705SXin Li       bool WantPthread = Args.hasArg(options::OPT_pthread) ||
9472*67e74705SXin Li                          Args.hasArg(options::OPT_pthreads);
9473*67e74705SXin Li 
9474*67e74705SXin Li       if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
9475*67e74705SXin Li                        options::OPT_fno_openmp, false)) {
9476*67e74705SXin Li         // OpenMP runtimes implies pthreads when using the GNU toolchain.
9477*67e74705SXin Li         // FIXME: Does this really make sense for all GNU toolchains?
9478*67e74705SXin Li         WantPthread = true;
9479*67e74705SXin Li 
9480*67e74705SXin Li         // Also link the particular OpenMP runtimes.
9481*67e74705SXin Li         switch (getOpenMPRuntime(ToolChain, Args)) {
9482*67e74705SXin Li         case OMPRT_OMP:
9483*67e74705SXin Li           CmdArgs.push_back("-lomp");
9484*67e74705SXin Li           break;
9485*67e74705SXin Li         case OMPRT_GOMP:
9486*67e74705SXin Li           CmdArgs.push_back("-lgomp");
9487*67e74705SXin Li 
9488*67e74705SXin Li           // FIXME: Exclude this for platforms with libgomp that don't require
9489*67e74705SXin Li           // librt. Most modern Linux platforms require it, but some may not.
9490*67e74705SXin Li           CmdArgs.push_back("-lrt");
9491*67e74705SXin Li           break;
9492*67e74705SXin Li         case OMPRT_IOMP5:
9493*67e74705SXin Li           CmdArgs.push_back("-liomp5");
9494*67e74705SXin Li           break;
9495*67e74705SXin Li         case OMPRT_Unknown:
9496*67e74705SXin Li           // Already diagnosed.
9497*67e74705SXin Li           break;
9498*67e74705SXin Li         }
9499*67e74705SXin Li       }
9500*67e74705SXin Li 
9501*67e74705SXin Li       AddRunTimeLibs(ToolChain, D, CmdArgs, Args);
9502*67e74705SXin Li 
9503*67e74705SXin Li       if (WantPthread && !isAndroid)
9504*67e74705SXin Li         CmdArgs.push_back("-lpthread");
9505*67e74705SXin Li 
9506*67e74705SXin Li       if (Args.hasArg(options::OPT_fsplit_stack))
9507*67e74705SXin Li         CmdArgs.push_back("--wrap=pthread_create");
9508*67e74705SXin Li 
9509*67e74705SXin Li       CmdArgs.push_back("-lc");
9510*67e74705SXin Li 
9511*67e74705SXin Li       // Add IAMCU specific libs, if needed.
9512*67e74705SXin Li       if (IsIAMCU)
9513*67e74705SXin Li         CmdArgs.push_back("-lgloss");
9514*67e74705SXin Li 
9515*67e74705SXin Li       if (Args.hasArg(options::OPT_static))
9516*67e74705SXin Li         CmdArgs.push_back("--end-group");
9517*67e74705SXin Li       else
9518*67e74705SXin Li         AddRunTimeLibs(ToolChain, D, CmdArgs, Args);
9519*67e74705SXin Li 
9520*67e74705SXin Li       // Add IAMCU specific libs (outside the group), if needed.
9521*67e74705SXin Li       if (IsIAMCU) {
9522*67e74705SXin Li         CmdArgs.push_back("--as-needed");
9523*67e74705SXin Li         CmdArgs.push_back("-lsoftfp");
9524*67e74705SXin Li         CmdArgs.push_back("--no-as-needed");
9525*67e74705SXin Li       }
9526*67e74705SXin Li     }
9527*67e74705SXin Li 
9528*67e74705SXin Li     if (!Args.hasArg(options::OPT_nostartfiles) && !IsIAMCU) {
9529*67e74705SXin Li       const char *crtend;
9530*67e74705SXin Li       if (Args.hasArg(options::OPT_shared))
9531*67e74705SXin Li         crtend = isAndroid ? "crtend_so.o" : "crtendS.o";
9532*67e74705SXin Li       else if (IsPIE)
9533*67e74705SXin Li         crtend = isAndroid ? "crtend_android.o" : "crtendS.o";
9534*67e74705SXin Li       else
9535*67e74705SXin Li         crtend = isAndroid ? "crtend_android.o" : "crtend.o";
9536*67e74705SXin Li 
9537*67e74705SXin Li       if (HasCRTBeginEndFiles)
9538*67e74705SXin Li         CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtend)));
9539*67e74705SXin Li       if (!isAndroid)
9540*67e74705SXin Li         CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o")));
9541*67e74705SXin Li     }
9542*67e74705SXin Li   }
9543*67e74705SXin Li 
9544*67e74705SXin Li   C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
9545*67e74705SXin Li }
9546*67e74705SXin Li 
9547*67e74705SXin Li // NaCl ARM assembly (inline or standalone) can be written with a set of macros
9548*67e74705SXin Li // for the various SFI requirements like register masking. The assembly tool
9549*67e74705SXin Li // inserts the file containing the macros as an input into all the assembly
9550*67e74705SXin Li // jobs.
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const9551*67e74705SXin Li void nacltools::AssemblerARM::ConstructJob(Compilation &C, const JobAction &JA,
9552*67e74705SXin Li                                            const InputInfo &Output,
9553*67e74705SXin Li                                            const InputInfoList &Inputs,
9554*67e74705SXin Li                                            const ArgList &Args,
9555*67e74705SXin Li                                            const char *LinkingOutput) const {
9556*67e74705SXin Li   const toolchains::NaClToolChain &ToolChain =
9557*67e74705SXin Li       static_cast<const toolchains::NaClToolChain &>(getToolChain());
9558*67e74705SXin Li   InputInfo NaClMacros(types::TY_PP_Asm, ToolChain.GetNaClArmMacrosPath(),
9559*67e74705SXin Li                        "nacl-arm-macros.s");
9560*67e74705SXin Li   InputInfoList NewInputs;
9561*67e74705SXin Li   NewInputs.push_back(NaClMacros);
9562*67e74705SXin Li   NewInputs.append(Inputs.begin(), Inputs.end());
9563*67e74705SXin Li   gnutools::Assembler::ConstructJob(C, JA, Output, NewInputs, Args,
9564*67e74705SXin Li                                     LinkingOutput);
9565*67e74705SXin Li }
9566*67e74705SXin Li 
9567*67e74705SXin Li // This is quite similar to gnutools::Linker::ConstructJob with changes that
9568*67e74705SXin Li // we use static by default, do not yet support sanitizers or LTO, and a few
9569*67e74705SXin Li // others. Eventually we can support more of that and hopefully migrate back
9570*67e74705SXin Li // to gnutools::Linker.
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const9571*67e74705SXin Li void nacltools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
9572*67e74705SXin Li                                      const InputInfo &Output,
9573*67e74705SXin Li                                      const InputInfoList &Inputs,
9574*67e74705SXin Li                                      const ArgList &Args,
9575*67e74705SXin Li                                      const char *LinkingOutput) const {
9576*67e74705SXin Li 
9577*67e74705SXin Li   const toolchains::NaClToolChain &ToolChain =
9578*67e74705SXin Li       static_cast<const toolchains::NaClToolChain &>(getToolChain());
9579*67e74705SXin Li   const Driver &D = ToolChain.getDriver();
9580*67e74705SXin Li   const llvm::Triple::ArchType Arch = ToolChain.getArch();
9581*67e74705SXin Li   const bool IsStatic =
9582*67e74705SXin Li       !Args.hasArg(options::OPT_dynamic) && !Args.hasArg(options::OPT_shared);
9583*67e74705SXin Li 
9584*67e74705SXin Li   ArgStringList CmdArgs;
9585*67e74705SXin Li 
9586*67e74705SXin Li   // Silence warning for "clang -g foo.o -o foo"
9587*67e74705SXin Li   Args.ClaimAllArgs(options::OPT_g_Group);
9588*67e74705SXin Li   // and "clang -emit-llvm foo.o -o foo"
9589*67e74705SXin Li   Args.ClaimAllArgs(options::OPT_emit_llvm);
9590*67e74705SXin Li   // and for "clang -w foo.o -o foo". Other warning options are already
9591*67e74705SXin Li   // handled somewhere else.
9592*67e74705SXin Li   Args.ClaimAllArgs(options::OPT_w);
9593*67e74705SXin Li 
9594*67e74705SXin Li   if (!D.SysRoot.empty())
9595*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
9596*67e74705SXin Li 
9597*67e74705SXin Li   if (Args.hasArg(options::OPT_rdynamic))
9598*67e74705SXin Li     CmdArgs.push_back("-export-dynamic");
9599*67e74705SXin Li 
9600*67e74705SXin Li   if (Args.hasArg(options::OPT_s))
9601*67e74705SXin Li     CmdArgs.push_back("-s");
9602*67e74705SXin Li 
9603*67e74705SXin Li   // NaClToolChain doesn't have ExtraOpts like Linux; the only relevant flag
9604*67e74705SXin Li   // from there is --build-id, which we do want.
9605*67e74705SXin Li   CmdArgs.push_back("--build-id");
9606*67e74705SXin Li 
9607*67e74705SXin Li   if (!IsStatic)
9608*67e74705SXin Li     CmdArgs.push_back("--eh-frame-hdr");
9609*67e74705SXin Li 
9610*67e74705SXin Li   CmdArgs.push_back("-m");
9611*67e74705SXin Li   if (Arch == llvm::Triple::x86)
9612*67e74705SXin Li     CmdArgs.push_back("elf_i386_nacl");
9613*67e74705SXin Li   else if (Arch == llvm::Triple::arm)
9614*67e74705SXin Li     CmdArgs.push_back("armelf_nacl");
9615*67e74705SXin Li   else if (Arch == llvm::Triple::x86_64)
9616*67e74705SXin Li     CmdArgs.push_back("elf_x86_64_nacl");
9617*67e74705SXin Li   else if (Arch == llvm::Triple::mipsel)
9618*67e74705SXin Li     CmdArgs.push_back("mipselelf_nacl");
9619*67e74705SXin Li   else
9620*67e74705SXin Li     D.Diag(diag::err_target_unsupported_arch) << ToolChain.getArchName()
9621*67e74705SXin Li                                               << "Native Client";
9622*67e74705SXin Li 
9623*67e74705SXin Li   if (IsStatic)
9624*67e74705SXin Li     CmdArgs.push_back("-static");
9625*67e74705SXin Li   else if (Args.hasArg(options::OPT_shared))
9626*67e74705SXin Li     CmdArgs.push_back("-shared");
9627*67e74705SXin Li 
9628*67e74705SXin Li   CmdArgs.push_back("-o");
9629*67e74705SXin Li   CmdArgs.push_back(Output.getFilename());
9630*67e74705SXin Li   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
9631*67e74705SXin Li     if (!Args.hasArg(options::OPT_shared))
9632*67e74705SXin Li       CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crt1.o")));
9633*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o")));
9634*67e74705SXin Li 
9635*67e74705SXin Li     const char *crtbegin;
9636*67e74705SXin Li     if (IsStatic)
9637*67e74705SXin Li       crtbegin = "crtbeginT.o";
9638*67e74705SXin Li     else if (Args.hasArg(options::OPT_shared))
9639*67e74705SXin Li       crtbegin = "crtbeginS.o";
9640*67e74705SXin Li     else
9641*67e74705SXin Li       crtbegin = "crtbegin.o";
9642*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin)));
9643*67e74705SXin Li   }
9644*67e74705SXin Li 
9645*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_L);
9646*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_u);
9647*67e74705SXin Li 
9648*67e74705SXin Li   ToolChain.AddFilePathLibArgs(Args, CmdArgs);
9649*67e74705SXin Li 
9650*67e74705SXin Li   if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
9651*67e74705SXin Li     CmdArgs.push_back("--no-demangle");
9652*67e74705SXin Li 
9653*67e74705SXin Li   AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
9654*67e74705SXin Li 
9655*67e74705SXin Li   if (D.CCCIsCXX() &&
9656*67e74705SXin Li       !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
9657*67e74705SXin Li     bool OnlyLibstdcxxStatic =
9658*67e74705SXin Li         Args.hasArg(options::OPT_static_libstdcxx) && !IsStatic;
9659*67e74705SXin Li     if (OnlyLibstdcxxStatic)
9660*67e74705SXin Li       CmdArgs.push_back("-Bstatic");
9661*67e74705SXin Li     ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
9662*67e74705SXin Li     if (OnlyLibstdcxxStatic)
9663*67e74705SXin Li       CmdArgs.push_back("-Bdynamic");
9664*67e74705SXin Li     CmdArgs.push_back("-lm");
9665*67e74705SXin Li   }
9666*67e74705SXin Li 
9667*67e74705SXin Li   if (!Args.hasArg(options::OPT_nostdlib)) {
9668*67e74705SXin Li     if (!Args.hasArg(options::OPT_nodefaultlibs)) {
9669*67e74705SXin Li       // Always use groups, since it has no effect on dynamic libraries.
9670*67e74705SXin Li       CmdArgs.push_back("--start-group");
9671*67e74705SXin Li       CmdArgs.push_back("-lc");
9672*67e74705SXin Li       // NaCl's libc++ currently requires libpthread, so just always include it
9673*67e74705SXin Li       // in the group for C++.
9674*67e74705SXin Li       if (Args.hasArg(options::OPT_pthread) ||
9675*67e74705SXin Li           Args.hasArg(options::OPT_pthreads) || D.CCCIsCXX()) {
9676*67e74705SXin Li         // Gold, used by Mips, handles nested groups differently than ld, and
9677*67e74705SXin Li         // without '-lnacl' it prefers symbols from libpthread.a over libnacl.a,
9678*67e74705SXin Li         // which is not a desired behaviour here.
9679*67e74705SXin Li         // See https://sourceware.org/ml/binutils/2015-03/msg00034.html
9680*67e74705SXin Li         if (getToolChain().getArch() == llvm::Triple::mipsel)
9681*67e74705SXin Li           CmdArgs.push_back("-lnacl");
9682*67e74705SXin Li 
9683*67e74705SXin Li         CmdArgs.push_back("-lpthread");
9684*67e74705SXin Li       }
9685*67e74705SXin Li 
9686*67e74705SXin Li       CmdArgs.push_back("-lgcc");
9687*67e74705SXin Li       CmdArgs.push_back("--as-needed");
9688*67e74705SXin Li       if (IsStatic)
9689*67e74705SXin Li         CmdArgs.push_back("-lgcc_eh");
9690*67e74705SXin Li       else
9691*67e74705SXin Li         CmdArgs.push_back("-lgcc_s");
9692*67e74705SXin Li       CmdArgs.push_back("--no-as-needed");
9693*67e74705SXin Li 
9694*67e74705SXin Li       // Mips needs to create and use pnacl_legacy library that contains
9695*67e74705SXin Li       // definitions from bitcode/pnaclmm.c and definitions for
9696*67e74705SXin Li       // __nacl_tp_tls_offset() and __nacl_tp_tdb_offset().
9697*67e74705SXin Li       if (getToolChain().getArch() == llvm::Triple::mipsel)
9698*67e74705SXin Li         CmdArgs.push_back("-lpnacl_legacy");
9699*67e74705SXin Li 
9700*67e74705SXin Li       CmdArgs.push_back("--end-group");
9701*67e74705SXin Li     }
9702*67e74705SXin Li 
9703*67e74705SXin Li     if (!Args.hasArg(options::OPT_nostartfiles)) {
9704*67e74705SXin Li       const char *crtend;
9705*67e74705SXin Li       if (Args.hasArg(options::OPT_shared))
9706*67e74705SXin Li         crtend = "crtendS.o";
9707*67e74705SXin Li       else
9708*67e74705SXin Li         crtend = "crtend.o";
9709*67e74705SXin Li 
9710*67e74705SXin Li       CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtend)));
9711*67e74705SXin Li       CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o")));
9712*67e74705SXin Li     }
9713*67e74705SXin Li   }
9714*67e74705SXin Li 
9715*67e74705SXin Li   const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath());
9716*67e74705SXin Li   C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
9717*67e74705SXin Li }
9718*67e74705SXin Li 
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const9719*67e74705SXin Li void minix::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
9720*67e74705SXin Li                                     const InputInfo &Output,
9721*67e74705SXin Li                                     const InputInfoList &Inputs,
9722*67e74705SXin Li                                     const ArgList &Args,
9723*67e74705SXin Li                                     const char *LinkingOutput) const {
9724*67e74705SXin Li   claimNoWarnArgs(Args);
9725*67e74705SXin Li   ArgStringList CmdArgs;
9726*67e74705SXin Li 
9727*67e74705SXin Li   Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
9728*67e74705SXin Li 
9729*67e74705SXin Li   CmdArgs.push_back("-o");
9730*67e74705SXin Li   CmdArgs.push_back(Output.getFilename());
9731*67e74705SXin Li 
9732*67e74705SXin Li   for (const auto &II : Inputs)
9733*67e74705SXin Li     CmdArgs.push_back(II.getFilename());
9734*67e74705SXin Li 
9735*67e74705SXin Li   const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
9736*67e74705SXin Li   C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
9737*67e74705SXin Li }
9738*67e74705SXin Li 
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const9739*67e74705SXin Li void minix::Linker::ConstructJob(Compilation &C, const JobAction &JA,
9740*67e74705SXin Li                                  const InputInfo &Output,
9741*67e74705SXin Li                                  const InputInfoList &Inputs,
9742*67e74705SXin Li                                  const ArgList &Args,
9743*67e74705SXin Li                                  const char *LinkingOutput) const {
9744*67e74705SXin Li   const Driver &D = getToolChain().getDriver();
9745*67e74705SXin Li   ArgStringList CmdArgs;
9746*67e74705SXin Li 
9747*67e74705SXin Li   if (Output.isFilename()) {
9748*67e74705SXin Li     CmdArgs.push_back("-o");
9749*67e74705SXin Li     CmdArgs.push_back(Output.getFilename());
9750*67e74705SXin Li   } else {
9751*67e74705SXin Li     assert(Output.isNothing() && "Invalid output.");
9752*67e74705SXin Li   }
9753*67e74705SXin Li 
9754*67e74705SXin Li   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
9755*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crt1.o")));
9756*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crti.o")));
9757*67e74705SXin Li     CmdArgs.push_back(
9758*67e74705SXin Li         Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o")));
9759*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtn.o")));
9760*67e74705SXin Li   }
9761*67e74705SXin Li 
9762*67e74705SXin Li   Args.AddAllArgs(CmdArgs,
9763*67e74705SXin Li                   {options::OPT_L, options::OPT_T_Group, options::OPT_e});
9764*67e74705SXin Li 
9765*67e74705SXin Li   AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
9766*67e74705SXin Li 
9767*67e74705SXin Li   getToolChain().addProfileRTLibs(Args, CmdArgs);
9768*67e74705SXin Li 
9769*67e74705SXin Li   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
9770*67e74705SXin Li     if (D.CCCIsCXX()) {
9771*67e74705SXin Li       getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
9772*67e74705SXin Li       CmdArgs.push_back("-lm");
9773*67e74705SXin Li     }
9774*67e74705SXin Li   }
9775*67e74705SXin Li 
9776*67e74705SXin Li   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
9777*67e74705SXin Li     if (Args.hasArg(options::OPT_pthread))
9778*67e74705SXin Li       CmdArgs.push_back("-lpthread");
9779*67e74705SXin Li     CmdArgs.push_back("-lc");
9780*67e74705SXin Li     CmdArgs.push_back("-lCompilerRT-Generic");
9781*67e74705SXin Li     CmdArgs.push_back("-L/usr/pkg/compiler-rt/lib");
9782*67e74705SXin Li     CmdArgs.push_back(
9783*67e74705SXin Li         Args.MakeArgString(getToolChain().GetFilePath("crtend.o")));
9784*67e74705SXin Li   }
9785*67e74705SXin Li 
9786*67e74705SXin Li   const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
9787*67e74705SXin Li   C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
9788*67e74705SXin Li }
9789*67e74705SXin Li 
9790*67e74705SXin Li /// DragonFly Tools
9791*67e74705SXin Li 
9792*67e74705SXin Li // For now, DragonFly Assemble does just about the same as for
9793*67e74705SXin Li // FreeBSD, but this may change soon.
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const9794*67e74705SXin Li void dragonfly::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
9795*67e74705SXin Li                                         const InputInfo &Output,
9796*67e74705SXin Li                                         const InputInfoList &Inputs,
9797*67e74705SXin Li                                         const ArgList &Args,
9798*67e74705SXin Li                                         const char *LinkingOutput) const {
9799*67e74705SXin Li   claimNoWarnArgs(Args);
9800*67e74705SXin Li   ArgStringList CmdArgs;
9801*67e74705SXin Li 
9802*67e74705SXin Li   // When building 32-bit code on DragonFly/pc64, we have to explicitly
9803*67e74705SXin Li   // instruct as in the base system to assemble 32-bit code.
9804*67e74705SXin Li   if (getToolChain().getArch() == llvm::Triple::x86)
9805*67e74705SXin Li     CmdArgs.push_back("--32");
9806*67e74705SXin Li 
9807*67e74705SXin Li   Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
9808*67e74705SXin Li 
9809*67e74705SXin Li   CmdArgs.push_back("-o");
9810*67e74705SXin Li   CmdArgs.push_back(Output.getFilename());
9811*67e74705SXin Li 
9812*67e74705SXin Li   for (const auto &II : Inputs)
9813*67e74705SXin Li     CmdArgs.push_back(II.getFilename());
9814*67e74705SXin Li 
9815*67e74705SXin Li   const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
9816*67e74705SXin Li   C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
9817*67e74705SXin Li }
9818*67e74705SXin Li 
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const9819*67e74705SXin Li void dragonfly::Linker::ConstructJob(Compilation &C, const JobAction &JA,
9820*67e74705SXin Li                                      const InputInfo &Output,
9821*67e74705SXin Li                                      const InputInfoList &Inputs,
9822*67e74705SXin Li                                      const ArgList &Args,
9823*67e74705SXin Li                                      const char *LinkingOutput) const {
9824*67e74705SXin Li   const Driver &D = getToolChain().getDriver();
9825*67e74705SXin Li   ArgStringList CmdArgs;
9826*67e74705SXin Li 
9827*67e74705SXin Li   if (!D.SysRoot.empty())
9828*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
9829*67e74705SXin Li 
9830*67e74705SXin Li   CmdArgs.push_back("--eh-frame-hdr");
9831*67e74705SXin Li   if (Args.hasArg(options::OPT_static)) {
9832*67e74705SXin Li     CmdArgs.push_back("-Bstatic");
9833*67e74705SXin Li   } else {
9834*67e74705SXin Li     if (Args.hasArg(options::OPT_rdynamic))
9835*67e74705SXin Li       CmdArgs.push_back("-export-dynamic");
9836*67e74705SXin Li     if (Args.hasArg(options::OPT_shared))
9837*67e74705SXin Li       CmdArgs.push_back("-Bshareable");
9838*67e74705SXin Li     else {
9839*67e74705SXin Li       CmdArgs.push_back("-dynamic-linker");
9840*67e74705SXin Li       CmdArgs.push_back("/usr/libexec/ld-elf.so.2");
9841*67e74705SXin Li     }
9842*67e74705SXin Li     CmdArgs.push_back("--hash-style=gnu");
9843*67e74705SXin Li     CmdArgs.push_back("--enable-new-dtags");
9844*67e74705SXin Li   }
9845*67e74705SXin Li 
9846*67e74705SXin Li   // When building 32-bit code on DragonFly/pc64, we have to explicitly
9847*67e74705SXin Li   // instruct ld in the base system to link 32-bit code.
9848*67e74705SXin Li   if (getToolChain().getArch() == llvm::Triple::x86) {
9849*67e74705SXin Li     CmdArgs.push_back("-m");
9850*67e74705SXin Li     CmdArgs.push_back("elf_i386");
9851*67e74705SXin Li   }
9852*67e74705SXin Li 
9853*67e74705SXin Li   if (Output.isFilename()) {
9854*67e74705SXin Li     CmdArgs.push_back("-o");
9855*67e74705SXin Li     CmdArgs.push_back(Output.getFilename());
9856*67e74705SXin Li   } else {
9857*67e74705SXin Li     assert(Output.isNothing() && "Invalid output.");
9858*67e74705SXin Li   }
9859*67e74705SXin Li 
9860*67e74705SXin Li   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
9861*67e74705SXin Li     if (!Args.hasArg(options::OPT_shared)) {
9862*67e74705SXin Li       if (Args.hasArg(options::OPT_pg))
9863*67e74705SXin Li         CmdArgs.push_back(
9864*67e74705SXin Li             Args.MakeArgString(getToolChain().GetFilePath("gcrt1.o")));
9865*67e74705SXin Li       else {
9866*67e74705SXin Li         if (Args.hasArg(options::OPT_pie))
9867*67e74705SXin Li           CmdArgs.push_back(
9868*67e74705SXin Li               Args.MakeArgString(getToolChain().GetFilePath("Scrt1.o")));
9869*67e74705SXin Li         else
9870*67e74705SXin Li           CmdArgs.push_back(
9871*67e74705SXin Li               Args.MakeArgString(getToolChain().GetFilePath("crt1.o")));
9872*67e74705SXin Li       }
9873*67e74705SXin Li     }
9874*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crti.o")));
9875*67e74705SXin Li     if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
9876*67e74705SXin Li       CmdArgs.push_back(
9877*67e74705SXin Li           Args.MakeArgString(getToolChain().GetFilePath("crtbeginS.o")));
9878*67e74705SXin Li     else
9879*67e74705SXin Li       CmdArgs.push_back(
9880*67e74705SXin Li           Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o")));
9881*67e74705SXin Li   }
9882*67e74705SXin Li 
9883*67e74705SXin Li   Args.AddAllArgs(CmdArgs,
9884*67e74705SXin Li                   {options::OPT_L, options::OPT_T_Group, options::OPT_e});
9885*67e74705SXin Li 
9886*67e74705SXin Li   AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
9887*67e74705SXin Li 
9888*67e74705SXin Li   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
9889*67e74705SXin Li     CmdArgs.push_back("-L/usr/lib/gcc50");
9890*67e74705SXin Li 
9891*67e74705SXin Li     if (!Args.hasArg(options::OPT_static)) {
9892*67e74705SXin Li       CmdArgs.push_back("-rpath");
9893*67e74705SXin Li       CmdArgs.push_back("/usr/lib/gcc50");
9894*67e74705SXin Li     }
9895*67e74705SXin Li 
9896*67e74705SXin Li     if (D.CCCIsCXX()) {
9897*67e74705SXin Li       getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
9898*67e74705SXin Li       CmdArgs.push_back("-lm");
9899*67e74705SXin Li     }
9900*67e74705SXin Li 
9901*67e74705SXin Li     if (Args.hasArg(options::OPT_pthread))
9902*67e74705SXin Li       CmdArgs.push_back("-lpthread");
9903*67e74705SXin Li 
9904*67e74705SXin Li     if (!Args.hasArg(options::OPT_nolibc)) {
9905*67e74705SXin Li       CmdArgs.push_back("-lc");
9906*67e74705SXin Li     }
9907*67e74705SXin Li 
9908*67e74705SXin Li     if (Args.hasArg(options::OPT_static) ||
9909*67e74705SXin Li         Args.hasArg(options::OPT_static_libgcc)) {
9910*67e74705SXin Li         CmdArgs.push_back("-lgcc");
9911*67e74705SXin Li         CmdArgs.push_back("-lgcc_eh");
9912*67e74705SXin Li     } else {
9913*67e74705SXin Li       if (Args.hasArg(options::OPT_shared_libgcc)) {
9914*67e74705SXin Li           CmdArgs.push_back("-lgcc_pic");
9915*67e74705SXin Li           if (!Args.hasArg(options::OPT_shared))
9916*67e74705SXin Li             CmdArgs.push_back("-lgcc");
9917*67e74705SXin Li       } else {
9918*67e74705SXin Li           CmdArgs.push_back("-lgcc");
9919*67e74705SXin Li           CmdArgs.push_back("--as-needed");
9920*67e74705SXin Li           CmdArgs.push_back("-lgcc_pic");
9921*67e74705SXin Li           CmdArgs.push_back("--no-as-needed");
9922*67e74705SXin Li       }
9923*67e74705SXin Li     }
9924*67e74705SXin Li   }
9925*67e74705SXin Li 
9926*67e74705SXin Li   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
9927*67e74705SXin Li     if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
9928*67e74705SXin Li       CmdArgs.push_back(
9929*67e74705SXin Li           Args.MakeArgString(getToolChain().GetFilePath("crtendS.o")));
9930*67e74705SXin Li     else
9931*67e74705SXin Li       CmdArgs.push_back(
9932*67e74705SXin Li           Args.MakeArgString(getToolChain().GetFilePath("crtend.o")));
9933*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtn.o")));
9934*67e74705SXin Li   }
9935*67e74705SXin Li 
9936*67e74705SXin Li   getToolChain().addProfileRTLibs(Args, CmdArgs);
9937*67e74705SXin Li 
9938*67e74705SXin Li   const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
9939*67e74705SXin Li   C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
9940*67e74705SXin Li }
9941*67e74705SXin Li 
9942*67e74705SXin Li // Try to find Exe from a Visual Studio distribution.  This first tries to find
9943*67e74705SXin Li // an installed copy of Visual Studio and, failing that, looks in the PATH,
9944*67e74705SXin Li // making sure that whatever executable that's found is not a same-named exe
9945*67e74705SXin Li // from clang itself to prevent clang from falling back to itself.
FindVisualStudioExecutable(const ToolChain & TC,const char * Exe,const char * ClangProgramPath)9946*67e74705SXin Li static std::string FindVisualStudioExecutable(const ToolChain &TC,
9947*67e74705SXin Li                                               const char *Exe,
9948*67e74705SXin Li                                               const char *ClangProgramPath) {
9949*67e74705SXin Li   const auto &MSVC = static_cast<const toolchains::MSVCToolChain &>(TC);
9950*67e74705SXin Li   std::string visualStudioBinDir;
9951*67e74705SXin Li   if (MSVC.getVisualStudioBinariesFolder(ClangProgramPath,
9952*67e74705SXin Li                                          visualStudioBinDir)) {
9953*67e74705SXin Li     SmallString<128> FilePath(visualStudioBinDir);
9954*67e74705SXin Li     llvm::sys::path::append(FilePath, Exe);
9955*67e74705SXin Li     if (llvm::sys::fs::can_execute(FilePath.c_str()))
9956*67e74705SXin Li       return FilePath.str();
9957*67e74705SXin Li   }
9958*67e74705SXin Li 
9959*67e74705SXin Li   return Exe;
9960*67e74705SXin Li }
9961*67e74705SXin Li 
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const9962*67e74705SXin Li void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA,
9963*67e74705SXin Li                                         const InputInfo &Output,
9964*67e74705SXin Li                                         const InputInfoList &Inputs,
9965*67e74705SXin Li                                         const ArgList &Args,
9966*67e74705SXin Li                                         const char *LinkingOutput) const {
9967*67e74705SXin Li   ArgStringList CmdArgs;
9968*67e74705SXin Li   const ToolChain &TC = getToolChain();
9969*67e74705SXin Li 
9970*67e74705SXin Li   assert((Output.isFilename() || Output.isNothing()) && "invalid output");
9971*67e74705SXin Li   if (Output.isFilename())
9972*67e74705SXin Li     CmdArgs.push_back(
9973*67e74705SXin Li         Args.MakeArgString(std::string("-out:") + Output.getFilename()));
9974*67e74705SXin Li 
9975*67e74705SXin Li   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles) &&
9976*67e74705SXin Li       !C.getDriver().IsCLMode())
9977*67e74705SXin Li     CmdArgs.push_back("-defaultlib:libcmt");
9978*67e74705SXin Li 
9979*67e74705SXin Li   if (!llvm::sys::Process::GetEnv("LIB")) {
9980*67e74705SXin Li     // If the VC environment hasn't been configured (perhaps because the user
9981*67e74705SXin Li     // did not run vcvarsall), try to build a consistent link environment.  If
9982*67e74705SXin Li     // the environment variable is set however, assume the user knows what
9983*67e74705SXin Li     // they're doing.
9984*67e74705SXin Li     std::string VisualStudioDir;
9985*67e74705SXin Li     const auto &MSVC = static_cast<const toolchains::MSVCToolChain &>(TC);
9986*67e74705SXin Li     if (MSVC.getVisualStudioInstallDir(VisualStudioDir)) {
9987*67e74705SXin Li       SmallString<128> LibDir(VisualStudioDir);
9988*67e74705SXin Li       llvm::sys::path::append(LibDir, "VC", "lib");
9989*67e74705SXin Li       switch (MSVC.getArch()) {
9990*67e74705SXin Li       case llvm::Triple::x86:
9991*67e74705SXin Li         // x86 just puts the libraries directly in lib
9992*67e74705SXin Li         break;
9993*67e74705SXin Li       case llvm::Triple::x86_64:
9994*67e74705SXin Li         llvm::sys::path::append(LibDir, "amd64");
9995*67e74705SXin Li         break;
9996*67e74705SXin Li       case llvm::Triple::arm:
9997*67e74705SXin Li         llvm::sys::path::append(LibDir, "arm");
9998*67e74705SXin Li         break;
9999*67e74705SXin Li       default:
10000*67e74705SXin Li         break;
10001*67e74705SXin Li       }
10002*67e74705SXin Li       CmdArgs.push_back(
10003*67e74705SXin Li           Args.MakeArgString(std::string("-libpath:") + LibDir.c_str()));
10004*67e74705SXin Li 
10005*67e74705SXin Li       if (MSVC.useUniversalCRT(VisualStudioDir)) {
10006*67e74705SXin Li         std::string UniversalCRTLibPath;
10007*67e74705SXin Li         if (MSVC.getUniversalCRTLibraryPath(UniversalCRTLibPath))
10008*67e74705SXin Li           CmdArgs.push_back(Args.MakeArgString(std::string("-libpath:") +
10009*67e74705SXin Li                                                UniversalCRTLibPath.c_str()));
10010*67e74705SXin Li       }
10011*67e74705SXin Li     }
10012*67e74705SXin Li 
10013*67e74705SXin Li     std::string WindowsSdkLibPath;
10014*67e74705SXin Li     if (MSVC.getWindowsSDKLibraryPath(WindowsSdkLibPath))
10015*67e74705SXin Li       CmdArgs.push_back(Args.MakeArgString(std::string("-libpath:") +
10016*67e74705SXin Li                                            WindowsSdkLibPath.c_str()));
10017*67e74705SXin Li   }
10018*67e74705SXin Li 
10019*67e74705SXin Li   if (!C.getDriver().IsCLMode() && Args.hasArg(options::OPT_L))
10020*67e74705SXin Li     for (const auto &LibPath : Args.getAllArgValues(options::OPT_L))
10021*67e74705SXin Li       CmdArgs.push_back(Args.MakeArgString("-libpath:" + LibPath));
10022*67e74705SXin Li 
10023*67e74705SXin Li   CmdArgs.push_back("-nologo");
10024*67e74705SXin Li 
10025*67e74705SXin Li   if (Args.hasArg(options::OPT_g_Group, options::OPT__SLASH_Z7,
10026*67e74705SXin Li                   options::OPT__SLASH_Zd))
10027*67e74705SXin Li     CmdArgs.push_back("-debug");
10028*67e74705SXin Li 
10029*67e74705SXin Li   bool DLL = Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd,
10030*67e74705SXin Li                          options::OPT_shared);
10031*67e74705SXin Li   if (DLL) {
10032*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString("-dll"));
10033*67e74705SXin Li 
10034*67e74705SXin Li     SmallString<128> ImplibName(Output.getFilename());
10035*67e74705SXin Li     llvm::sys::path::replace_extension(ImplibName, "lib");
10036*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(std::string("-implib:") + ImplibName));
10037*67e74705SXin Li   }
10038*67e74705SXin Li 
10039*67e74705SXin Li   if (TC.getSanitizerArgs().needsAsanRt()) {
10040*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString("-debug"));
10041*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString("-incremental:no"));
10042*67e74705SXin Li     if (Args.hasArg(options::OPT__SLASH_MD, options::OPT__SLASH_MDd)) {
10043*67e74705SXin Li       for (const auto &Lib : {"asan_dynamic", "asan_dynamic_runtime_thunk"})
10044*67e74705SXin Li         CmdArgs.push_back(TC.getCompilerRTArgString(Args, Lib));
10045*67e74705SXin Li       // Make sure the dynamic runtime thunk is not optimized out at link time
10046*67e74705SXin Li       // to ensure proper SEH handling.
10047*67e74705SXin Li       CmdArgs.push_back(Args.MakeArgString("-include:___asan_seh_interceptor"));
10048*67e74705SXin Li     } else if (DLL) {
10049*67e74705SXin Li       CmdArgs.push_back(TC.getCompilerRTArgString(Args, "asan_dll_thunk"));
10050*67e74705SXin Li     } else {
10051*67e74705SXin Li       for (const auto &Lib : {"asan", "asan_cxx"})
10052*67e74705SXin Li         CmdArgs.push_back(TC.getCompilerRTArgString(Args, Lib));
10053*67e74705SXin Li     }
10054*67e74705SXin Li   }
10055*67e74705SXin Li 
10056*67e74705SXin Li   Args.AddAllArgValues(CmdArgs, options::OPT__SLASH_link);
10057*67e74705SXin Li 
10058*67e74705SXin Li   if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
10059*67e74705SXin Li                    options::OPT_fno_openmp, false)) {
10060*67e74705SXin Li     CmdArgs.push_back("-nodefaultlib:vcomp.lib");
10061*67e74705SXin Li     CmdArgs.push_back("-nodefaultlib:vcompd.lib");
10062*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(std::string("-libpath:") +
10063*67e74705SXin Li                                          TC.getDriver().Dir + "/../lib"));
10064*67e74705SXin Li     switch (getOpenMPRuntime(getToolChain(), Args)) {
10065*67e74705SXin Li     case OMPRT_OMP:
10066*67e74705SXin Li       CmdArgs.push_back("-defaultlib:libomp.lib");
10067*67e74705SXin Li       break;
10068*67e74705SXin Li     case OMPRT_IOMP5:
10069*67e74705SXin Li       CmdArgs.push_back("-defaultlib:libiomp5md.lib");
10070*67e74705SXin Li       break;
10071*67e74705SXin Li     case OMPRT_GOMP:
10072*67e74705SXin Li       break;
10073*67e74705SXin Li     case OMPRT_Unknown:
10074*67e74705SXin Li       // Already diagnosed.
10075*67e74705SXin Li       break;
10076*67e74705SXin Li     }
10077*67e74705SXin Li   }
10078*67e74705SXin Li 
10079*67e74705SXin Li   // Add compiler-rt lib in case if it was explicitly
10080*67e74705SXin Li   // specified as an argument for --rtlib option.
10081*67e74705SXin Li   if (!Args.hasArg(options::OPT_nostdlib)) {
10082*67e74705SXin Li     AddRunTimeLibs(TC, TC.getDriver(), CmdArgs, Args);
10083*67e74705SXin Li   }
10084*67e74705SXin Li 
10085*67e74705SXin Li   // Add filenames, libraries, and other linker inputs.
10086*67e74705SXin Li   for (const auto &Input : Inputs) {
10087*67e74705SXin Li     if (Input.isFilename()) {
10088*67e74705SXin Li       CmdArgs.push_back(Input.getFilename());
10089*67e74705SXin Li       continue;
10090*67e74705SXin Li     }
10091*67e74705SXin Li 
10092*67e74705SXin Li     const Arg &A = Input.getInputArg();
10093*67e74705SXin Li 
10094*67e74705SXin Li     // Render -l options differently for the MSVC linker.
10095*67e74705SXin Li     if (A.getOption().matches(options::OPT_l)) {
10096*67e74705SXin Li       StringRef Lib = A.getValue();
10097*67e74705SXin Li       const char *LinkLibArg;
10098*67e74705SXin Li       if (Lib.endswith(".lib"))
10099*67e74705SXin Li         LinkLibArg = Args.MakeArgString(Lib);
10100*67e74705SXin Li       else
10101*67e74705SXin Li         LinkLibArg = Args.MakeArgString(Lib + ".lib");
10102*67e74705SXin Li       CmdArgs.push_back(LinkLibArg);
10103*67e74705SXin Li       continue;
10104*67e74705SXin Li     }
10105*67e74705SXin Li 
10106*67e74705SXin Li     // Otherwise, this is some other kind of linker input option like -Wl, -z,
10107*67e74705SXin Li     // or -L. Render it, even if MSVC doesn't understand it.
10108*67e74705SXin Li     A.renderAsInput(Args, CmdArgs);
10109*67e74705SXin Li   }
10110*67e74705SXin Li 
10111*67e74705SXin Li   TC.addProfileRTLibs(Args, CmdArgs);
10112*67e74705SXin Li 
10113*67e74705SXin Li   // We need to special case some linker paths.  In the case of lld, we need to
10114*67e74705SXin Li   // translate 'lld' into 'lld-link', and in the case of the regular msvc
10115*67e74705SXin Li   // linker, we need to use a special search algorithm.
10116*67e74705SXin Li   llvm::SmallString<128> linkPath;
10117*67e74705SXin Li   StringRef Linker = Args.getLastArgValue(options::OPT_fuse_ld_EQ, "link");
10118*67e74705SXin Li   if (Linker.equals_lower("lld"))
10119*67e74705SXin Li     Linker = "lld-link";
10120*67e74705SXin Li 
10121*67e74705SXin Li   if (Linker.equals_lower("link")) {
10122*67e74705SXin Li     // If we're using the MSVC linker, it's not sufficient to just use link
10123*67e74705SXin Li     // from the program PATH, because other environments like GnuWin32 install
10124*67e74705SXin Li     // their own link.exe which may come first.
10125*67e74705SXin Li     linkPath = FindVisualStudioExecutable(TC, "link.exe",
10126*67e74705SXin Li                                           C.getDriver().getClangProgramPath());
10127*67e74705SXin Li   } else {
10128*67e74705SXin Li     linkPath = Linker;
10129*67e74705SXin Li     llvm::sys::path::replace_extension(linkPath, "exe");
10130*67e74705SXin Li     linkPath = TC.GetProgramPath(linkPath.c_str());
10131*67e74705SXin Li   }
10132*67e74705SXin Li 
10133*67e74705SXin Li   const char *Exec = Args.MakeArgString(linkPath);
10134*67e74705SXin Li   C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
10135*67e74705SXin Li }
10136*67e74705SXin Li 
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const10137*67e74705SXin Li void visualstudio::Compiler::ConstructJob(Compilation &C, const JobAction &JA,
10138*67e74705SXin Li                                           const InputInfo &Output,
10139*67e74705SXin Li                                           const InputInfoList &Inputs,
10140*67e74705SXin Li                                           const ArgList &Args,
10141*67e74705SXin Li                                           const char *LinkingOutput) const {
10142*67e74705SXin Li   C.addCommand(GetCommand(C, JA, Output, Inputs, Args, LinkingOutput));
10143*67e74705SXin Li }
10144*67e74705SXin Li 
GetCommand(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const10145*67e74705SXin Li std::unique_ptr<Command> visualstudio::Compiler::GetCommand(
10146*67e74705SXin Li     Compilation &C, const JobAction &JA, const InputInfo &Output,
10147*67e74705SXin Li     const InputInfoList &Inputs, const ArgList &Args,
10148*67e74705SXin Li     const char *LinkingOutput) const {
10149*67e74705SXin Li   ArgStringList CmdArgs;
10150*67e74705SXin Li   CmdArgs.push_back("/nologo");
10151*67e74705SXin Li   CmdArgs.push_back("/c");  // Compile only.
10152*67e74705SXin Li   CmdArgs.push_back("/W0"); // No warnings.
10153*67e74705SXin Li 
10154*67e74705SXin Li   // The goal is to be able to invoke this tool correctly based on
10155*67e74705SXin Li   // any flag accepted by clang-cl.
10156*67e74705SXin Li 
10157*67e74705SXin Li   // These are spelled the same way in clang and cl.exe,.
10158*67e74705SXin Li   Args.AddAllArgs(CmdArgs, {options::OPT_D, options::OPT_U, options::OPT_I});
10159*67e74705SXin Li 
10160*67e74705SXin Li   // Optimization level.
10161*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_fbuiltin, options::OPT_fno_builtin))
10162*67e74705SXin Li     CmdArgs.push_back(A->getOption().getID() == options::OPT_fbuiltin ? "/Oi"
10163*67e74705SXin Li                                                                       : "/Oi-");
10164*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_O, options::OPT_O0)) {
10165*67e74705SXin Li     if (A->getOption().getID() == options::OPT_O0) {
10166*67e74705SXin Li       CmdArgs.push_back("/Od");
10167*67e74705SXin Li     } else {
10168*67e74705SXin Li       CmdArgs.push_back("/Og");
10169*67e74705SXin Li 
10170*67e74705SXin Li       StringRef OptLevel = A->getValue();
10171*67e74705SXin Li       if (OptLevel == "s" || OptLevel == "z")
10172*67e74705SXin Li         CmdArgs.push_back("/Os");
10173*67e74705SXin Li       else
10174*67e74705SXin Li         CmdArgs.push_back("/Ot");
10175*67e74705SXin Li 
10176*67e74705SXin Li       CmdArgs.push_back("/Ob2");
10177*67e74705SXin Li     }
10178*67e74705SXin Li   }
10179*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_fomit_frame_pointer,
10180*67e74705SXin Li                                options::OPT_fno_omit_frame_pointer))
10181*67e74705SXin Li     CmdArgs.push_back(A->getOption().getID() == options::OPT_fomit_frame_pointer
10182*67e74705SXin Li                           ? "/Oy"
10183*67e74705SXin Li                           : "/Oy-");
10184*67e74705SXin Li   if (!Args.hasArg(options::OPT_fwritable_strings))
10185*67e74705SXin Li     CmdArgs.push_back("/GF");
10186*67e74705SXin Li 
10187*67e74705SXin Li   // Flags for which clang-cl has an alias.
10188*67e74705SXin Li   // FIXME: How can we ensure this stays in sync with relevant clang-cl options?
10189*67e74705SXin Li 
10190*67e74705SXin Li   if (Args.hasFlag(options::OPT__SLASH_GR_, options::OPT__SLASH_GR,
10191*67e74705SXin Li                    /*default=*/false))
10192*67e74705SXin Li     CmdArgs.push_back("/GR-");
10193*67e74705SXin Li 
10194*67e74705SXin Li   if (Args.hasFlag(options::OPT__SLASH_GS_, options::OPT__SLASH_GS,
10195*67e74705SXin Li                    /*default=*/false))
10196*67e74705SXin Li     CmdArgs.push_back("/GS-");
10197*67e74705SXin Li 
10198*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_ffunction_sections,
10199*67e74705SXin Li                                options::OPT_fno_function_sections))
10200*67e74705SXin Li     CmdArgs.push_back(A->getOption().getID() == options::OPT_ffunction_sections
10201*67e74705SXin Li                           ? "/Gy"
10202*67e74705SXin Li                           : "/Gy-");
10203*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_fdata_sections,
10204*67e74705SXin Li                                options::OPT_fno_data_sections))
10205*67e74705SXin Li     CmdArgs.push_back(
10206*67e74705SXin Li         A->getOption().getID() == options::OPT_fdata_sections ? "/Gw" : "/Gw-");
10207*67e74705SXin Li   if (Args.hasArg(options::OPT_fsyntax_only))
10208*67e74705SXin Li     CmdArgs.push_back("/Zs");
10209*67e74705SXin Li   if (Args.hasArg(options::OPT_g_Flag, options::OPT_gline_tables_only,
10210*67e74705SXin Li                   options::OPT__SLASH_Z7))
10211*67e74705SXin Li     CmdArgs.push_back("/Z7");
10212*67e74705SXin Li 
10213*67e74705SXin Li   std::vector<std::string> Includes =
10214*67e74705SXin Li       Args.getAllArgValues(options::OPT_include);
10215*67e74705SXin Li   for (const auto &Include : Includes)
10216*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(std::string("/FI") + Include));
10217*67e74705SXin Li 
10218*67e74705SXin Li   // Flags that can simply be passed through.
10219*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT__SLASH_LD);
10220*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT__SLASH_LDd);
10221*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT__SLASH_GX);
10222*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT__SLASH_GX_);
10223*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT__SLASH_EH);
10224*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT__SLASH_Zl);
10225*67e74705SXin Li 
10226*67e74705SXin Li   // The order of these flags is relevant, so pick the last one.
10227*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT__SLASH_MD, options::OPT__SLASH_MDd,
10228*67e74705SXin Li                                options::OPT__SLASH_MT, options::OPT__SLASH_MTd))
10229*67e74705SXin Li     A->render(Args, CmdArgs);
10230*67e74705SXin Li 
10231*67e74705SXin Li   // Pass through all unknown arguments so that the fallback command can see
10232*67e74705SXin Li   // them too.
10233*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_UNKNOWN);
10234*67e74705SXin Li 
10235*67e74705SXin Li   // Input filename.
10236*67e74705SXin Li   assert(Inputs.size() == 1);
10237*67e74705SXin Li   const InputInfo &II = Inputs[0];
10238*67e74705SXin Li   assert(II.getType() == types::TY_C || II.getType() == types::TY_CXX);
10239*67e74705SXin Li   CmdArgs.push_back(II.getType() == types::TY_C ? "/Tc" : "/Tp");
10240*67e74705SXin Li   if (II.isFilename())
10241*67e74705SXin Li     CmdArgs.push_back(II.getFilename());
10242*67e74705SXin Li   else
10243*67e74705SXin Li     II.getInputArg().renderAsInput(Args, CmdArgs);
10244*67e74705SXin Li 
10245*67e74705SXin Li   // Output filename.
10246*67e74705SXin Li   assert(Output.getType() == types::TY_Object);
10247*67e74705SXin Li   const char *Fo =
10248*67e74705SXin Li       Args.MakeArgString(std::string("/Fo") + Output.getFilename());
10249*67e74705SXin Li   CmdArgs.push_back(Fo);
10250*67e74705SXin Li 
10251*67e74705SXin Li   const Driver &D = getToolChain().getDriver();
10252*67e74705SXin Li   std::string Exec = FindVisualStudioExecutable(getToolChain(), "cl.exe",
10253*67e74705SXin Li                                                 D.getClangProgramPath());
10254*67e74705SXin Li   return llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Exec),
10255*67e74705SXin Li                                     CmdArgs, Inputs);
10256*67e74705SXin Li }
10257*67e74705SXin Li 
10258*67e74705SXin Li /// MinGW Tools
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const10259*67e74705SXin Li void MinGW::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
10260*67e74705SXin Li                                     const InputInfo &Output,
10261*67e74705SXin Li                                     const InputInfoList &Inputs,
10262*67e74705SXin Li                                     const ArgList &Args,
10263*67e74705SXin Li                                     const char *LinkingOutput) const {
10264*67e74705SXin Li   claimNoWarnArgs(Args);
10265*67e74705SXin Li   ArgStringList CmdArgs;
10266*67e74705SXin Li 
10267*67e74705SXin Li   if (getToolChain().getArch() == llvm::Triple::x86) {
10268*67e74705SXin Li     CmdArgs.push_back("--32");
10269*67e74705SXin Li   } else if (getToolChain().getArch() == llvm::Triple::x86_64) {
10270*67e74705SXin Li     CmdArgs.push_back("--64");
10271*67e74705SXin Li   }
10272*67e74705SXin Li 
10273*67e74705SXin Li   Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
10274*67e74705SXin Li 
10275*67e74705SXin Li   CmdArgs.push_back("-o");
10276*67e74705SXin Li   CmdArgs.push_back(Output.getFilename());
10277*67e74705SXin Li 
10278*67e74705SXin Li   for (const auto &II : Inputs)
10279*67e74705SXin Li     CmdArgs.push_back(II.getFilename());
10280*67e74705SXin Li 
10281*67e74705SXin Li   const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
10282*67e74705SXin Li   C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
10283*67e74705SXin Li 
10284*67e74705SXin Li   if (Args.hasArg(options::OPT_gsplit_dwarf))
10285*67e74705SXin Li     SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output,
10286*67e74705SXin Li                    SplitDebugName(Args, Inputs[0]));
10287*67e74705SXin Li }
10288*67e74705SXin Li 
AddLibGCC(const ArgList & Args,ArgStringList & CmdArgs) const10289*67e74705SXin Li void MinGW::Linker::AddLibGCC(const ArgList &Args,
10290*67e74705SXin Li                               ArgStringList &CmdArgs) const {
10291*67e74705SXin Li   if (Args.hasArg(options::OPT_mthreads))
10292*67e74705SXin Li     CmdArgs.push_back("-lmingwthrd");
10293*67e74705SXin Li   CmdArgs.push_back("-lmingw32");
10294*67e74705SXin Li 
10295*67e74705SXin Li   // Make use of compiler-rt if --rtlib option is used
10296*67e74705SXin Li   ToolChain::RuntimeLibType RLT = getToolChain().GetRuntimeLibType(Args);
10297*67e74705SXin Li   if (RLT == ToolChain::RLT_Libgcc) {
10298*67e74705SXin Li     bool Static = Args.hasArg(options::OPT_static_libgcc) ||
10299*67e74705SXin Li                   Args.hasArg(options::OPT_static);
10300*67e74705SXin Li     bool Shared = Args.hasArg(options::OPT_shared);
10301*67e74705SXin Li     bool CXX = getToolChain().getDriver().CCCIsCXX();
10302*67e74705SXin Li 
10303*67e74705SXin Li     if (Static || (!CXX && !Shared)) {
10304*67e74705SXin Li       CmdArgs.push_back("-lgcc");
10305*67e74705SXin Li       CmdArgs.push_back("-lgcc_eh");
10306*67e74705SXin Li     } else {
10307*67e74705SXin Li       CmdArgs.push_back("-lgcc_s");
10308*67e74705SXin Li       CmdArgs.push_back("-lgcc");
10309*67e74705SXin Li     }
10310*67e74705SXin Li   } else {
10311*67e74705SXin Li     AddRunTimeLibs(getToolChain(), getToolChain().getDriver(), CmdArgs, Args);
10312*67e74705SXin Li   }
10313*67e74705SXin Li 
10314*67e74705SXin Li   CmdArgs.push_back("-lmoldname");
10315*67e74705SXin Li   CmdArgs.push_back("-lmingwex");
10316*67e74705SXin Li   CmdArgs.push_back("-lmsvcrt");
10317*67e74705SXin Li }
10318*67e74705SXin Li 
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const10319*67e74705SXin Li void MinGW::Linker::ConstructJob(Compilation &C, const JobAction &JA,
10320*67e74705SXin Li                                  const InputInfo &Output,
10321*67e74705SXin Li                                  const InputInfoList &Inputs,
10322*67e74705SXin Li                                  const ArgList &Args,
10323*67e74705SXin Li                                  const char *LinkingOutput) const {
10324*67e74705SXin Li   const ToolChain &TC = getToolChain();
10325*67e74705SXin Li   const Driver &D = TC.getDriver();
10326*67e74705SXin Li   // const SanitizerArgs &Sanitize = TC.getSanitizerArgs();
10327*67e74705SXin Li 
10328*67e74705SXin Li   ArgStringList CmdArgs;
10329*67e74705SXin Li 
10330*67e74705SXin Li   // Silence warning for "clang -g foo.o -o foo"
10331*67e74705SXin Li   Args.ClaimAllArgs(options::OPT_g_Group);
10332*67e74705SXin Li   // and "clang -emit-llvm foo.o -o foo"
10333*67e74705SXin Li   Args.ClaimAllArgs(options::OPT_emit_llvm);
10334*67e74705SXin Li   // and for "clang -w foo.o -o foo". Other warning options are already
10335*67e74705SXin Li   // handled somewhere else.
10336*67e74705SXin Li   Args.ClaimAllArgs(options::OPT_w);
10337*67e74705SXin Li 
10338*67e74705SXin Li   StringRef LinkerName = Args.getLastArgValue(options::OPT_fuse_ld_EQ, "ld");
10339*67e74705SXin Li   if (LinkerName.equals_lower("lld")) {
10340*67e74705SXin Li     CmdArgs.push_back("-flavor");
10341*67e74705SXin Li     CmdArgs.push_back("gnu");
10342*67e74705SXin Li   } else if (!LinkerName.equals_lower("ld")) {
10343*67e74705SXin Li     D.Diag(diag::err_drv_unsupported_linker) << LinkerName;
10344*67e74705SXin Li   }
10345*67e74705SXin Li 
10346*67e74705SXin Li   if (!D.SysRoot.empty())
10347*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
10348*67e74705SXin Li 
10349*67e74705SXin Li   if (Args.hasArg(options::OPT_s))
10350*67e74705SXin Li     CmdArgs.push_back("-s");
10351*67e74705SXin Li 
10352*67e74705SXin Li   CmdArgs.push_back("-m");
10353*67e74705SXin Li   if (TC.getArch() == llvm::Triple::x86)
10354*67e74705SXin Li     CmdArgs.push_back("i386pe");
10355*67e74705SXin Li   if (TC.getArch() == llvm::Triple::x86_64)
10356*67e74705SXin Li     CmdArgs.push_back("i386pep");
10357*67e74705SXin Li   if (TC.getArch() == llvm::Triple::arm)
10358*67e74705SXin Li     CmdArgs.push_back("thumb2pe");
10359*67e74705SXin Li 
10360*67e74705SXin Li   if (Args.hasArg(options::OPT_mwindows)) {
10361*67e74705SXin Li     CmdArgs.push_back("--subsystem");
10362*67e74705SXin Li     CmdArgs.push_back("windows");
10363*67e74705SXin Li   } else if (Args.hasArg(options::OPT_mconsole)) {
10364*67e74705SXin Li     CmdArgs.push_back("--subsystem");
10365*67e74705SXin Li     CmdArgs.push_back("console");
10366*67e74705SXin Li   }
10367*67e74705SXin Li 
10368*67e74705SXin Li   if (Args.hasArg(options::OPT_static))
10369*67e74705SXin Li     CmdArgs.push_back("-Bstatic");
10370*67e74705SXin Li   else {
10371*67e74705SXin Li     if (Args.hasArg(options::OPT_mdll))
10372*67e74705SXin Li       CmdArgs.push_back("--dll");
10373*67e74705SXin Li     else if (Args.hasArg(options::OPT_shared))
10374*67e74705SXin Li       CmdArgs.push_back("--shared");
10375*67e74705SXin Li     CmdArgs.push_back("-Bdynamic");
10376*67e74705SXin Li     if (Args.hasArg(options::OPT_mdll) || Args.hasArg(options::OPT_shared)) {
10377*67e74705SXin Li       CmdArgs.push_back("-e");
10378*67e74705SXin Li       if (TC.getArch() == llvm::Triple::x86)
10379*67e74705SXin Li         CmdArgs.push_back("_DllMainCRTStartup@12");
10380*67e74705SXin Li       else
10381*67e74705SXin Li         CmdArgs.push_back("DllMainCRTStartup");
10382*67e74705SXin Li       CmdArgs.push_back("--enable-auto-image-base");
10383*67e74705SXin Li     }
10384*67e74705SXin Li   }
10385*67e74705SXin Li 
10386*67e74705SXin Li   CmdArgs.push_back("-o");
10387*67e74705SXin Li   CmdArgs.push_back(Output.getFilename());
10388*67e74705SXin Li 
10389*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_e);
10390*67e74705SXin Li   // FIXME: add -N, -n flags
10391*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_r);
10392*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_s);
10393*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_t);
10394*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_u_Group);
10395*67e74705SXin Li   Args.AddLastArg(CmdArgs, options::OPT_Z_Flag);
10396*67e74705SXin Li 
10397*67e74705SXin Li   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
10398*67e74705SXin Li     if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_mdll)) {
10399*67e74705SXin Li       CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("dllcrt2.o")));
10400*67e74705SXin Li     } else {
10401*67e74705SXin Li       if (Args.hasArg(options::OPT_municode))
10402*67e74705SXin Li         CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crt2u.o")));
10403*67e74705SXin Li       else
10404*67e74705SXin Li         CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crt2.o")));
10405*67e74705SXin Li     }
10406*67e74705SXin Li     if (Args.hasArg(options::OPT_pg))
10407*67e74705SXin Li       CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("gcrt2.o")));
10408*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crtbegin.o")));
10409*67e74705SXin Li   }
10410*67e74705SXin Li 
10411*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_L);
10412*67e74705SXin Li   TC.AddFilePathLibArgs(Args, CmdArgs);
10413*67e74705SXin Li   AddLinkerInputs(TC, Inputs, Args, CmdArgs);
10414*67e74705SXin Li 
10415*67e74705SXin Li   // TODO: Add ASan stuff here
10416*67e74705SXin Li 
10417*67e74705SXin Li   // TODO: Add profile stuff here
10418*67e74705SXin Li 
10419*67e74705SXin Li   if (D.CCCIsCXX() &&
10420*67e74705SXin Li       !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
10421*67e74705SXin Li     bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
10422*67e74705SXin Li                                !Args.hasArg(options::OPT_static);
10423*67e74705SXin Li     if (OnlyLibstdcxxStatic)
10424*67e74705SXin Li       CmdArgs.push_back("-Bstatic");
10425*67e74705SXin Li     TC.AddCXXStdlibLibArgs(Args, CmdArgs);
10426*67e74705SXin Li     if (OnlyLibstdcxxStatic)
10427*67e74705SXin Li       CmdArgs.push_back("-Bdynamic");
10428*67e74705SXin Li   }
10429*67e74705SXin Li 
10430*67e74705SXin Li   if (!Args.hasArg(options::OPT_nostdlib)) {
10431*67e74705SXin Li     if (!Args.hasArg(options::OPT_nodefaultlibs)) {
10432*67e74705SXin Li       if (Args.hasArg(options::OPT_static))
10433*67e74705SXin Li         CmdArgs.push_back("--start-group");
10434*67e74705SXin Li 
10435*67e74705SXin Li       if (Args.hasArg(options::OPT_fstack_protector) ||
10436*67e74705SXin Li           Args.hasArg(options::OPT_fstack_protector_strong) ||
10437*67e74705SXin Li           Args.hasArg(options::OPT_fstack_protector_all)) {
10438*67e74705SXin Li         CmdArgs.push_back("-lssp_nonshared");
10439*67e74705SXin Li         CmdArgs.push_back("-lssp");
10440*67e74705SXin Li       }
10441*67e74705SXin Li       if (Args.hasArg(options::OPT_fopenmp))
10442*67e74705SXin Li         CmdArgs.push_back("-lgomp");
10443*67e74705SXin Li 
10444*67e74705SXin Li       AddLibGCC(Args, CmdArgs);
10445*67e74705SXin Li 
10446*67e74705SXin Li       if (Args.hasArg(options::OPT_pg))
10447*67e74705SXin Li         CmdArgs.push_back("-lgmon");
10448*67e74705SXin Li 
10449*67e74705SXin Li       if (Args.hasArg(options::OPT_pthread))
10450*67e74705SXin Li         CmdArgs.push_back("-lpthread");
10451*67e74705SXin Li 
10452*67e74705SXin Li       // add system libraries
10453*67e74705SXin Li       if (Args.hasArg(options::OPT_mwindows)) {
10454*67e74705SXin Li         CmdArgs.push_back("-lgdi32");
10455*67e74705SXin Li         CmdArgs.push_back("-lcomdlg32");
10456*67e74705SXin Li       }
10457*67e74705SXin Li       CmdArgs.push_back("-ladvapi32");
10458*67e74705SXin Li       CmdArgs.push_back("-lshell32");
10459*67e74705SXin Li       CmdArgs.push_back("-luser32");
10460*67e74705SXin Li       CmdArgs.push_back("-lkernel32");
10461*67e74705SXin Li 
10462*67e74705SXin Li       if (Args.hasArg(options::OPT_static))
10463*67e74705SXin Li         CmdArgs.push_back("--end-group");
10464*67e74705SXin Li       else if (!LinkerName.equals_lower("lld"))
10465*67e74705SXin Li         AddLibGCC(Args, CmdArgs);
10466*67e74705SXin Li     }
10467*67e74705SXin Li 
10468*67e74705SXin Li     if (!Args.hasArg(options::OPT_nostartfiles)) {
10469*67e74705SXin Li       // Add crtfastmath.o if available and fast math is enabled.
10470*67e74705SXin Li       TC.AddFastMathRuntimeIfAvailable(Args, CmdArgs);
10471*67e74705SXin Li 
10472*67e74705SXin Li       CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crtend.o")));
10473*67e74705SXin Li     }
10474*67e74705SXin Li   }
10475*67e74705SXin Li   const char *Exec = Args.MakeArgString(TC.GetProgramPath(LinkerName.data()));
10476*67e74705SXin Li   C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
10477*67e74705SXin Li }
10478*67e74705SXin Li 
10479*67e74705SXin Li /// XCore Tools
10480*67e74705SXin Li // We pass assemble and link construction to the xcc tool.
10481*67e74705SXin Li 
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const10482*67e74705SXin Li void XCore::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
10483*67e74705SXin Li                                     const InputInfo &Output,
10484*67e74705SXin Li                                     const InputInfoList &Inputs,
10485*67e74705SXin Li                                     const ArgList &Args,
10486*67e74705SXin Li                                     const char *LinkingOutput) const {
10487*67e74705SXin Li   claimNoWarnArgs(Args);
10488*67e74705SXin Li   ArgStringList CmdArgs;
10489*67e74705SXin Li 
10490*67e74705SXin Li   CmdArgs.push_back("-o");
10491*67e74705SXin Li   CmdArgs.push_back(Output.getFilename());
10492*67e74705SXin Li 
10493*67e74705SXin Li   CmdArgs.push_back("-c");
10494*67e74705SXin Li 
10495*67e74705SXin Li   if (Args.hasArg(options::OPT_v))
10496*67e74705SXin Li     CmdArgs.push_back("-v");
10497*67e74705SXin Li 
10498*67e74705SXin Li   if (Arg *A = Args.getLastArg(options::OPT_g_Group))
10499*67e74705SXin Li     if (!A->getOption().matches(options::OPT_g0))
10500*67e74705SXin Li       CmdArgs.push_back("-g");
10501*67e74705SXin Li 
10502*67e74705SXin Li   if (Args.hasFlag(options::OPT_fverbose_asm, options::OPT_fno_verbose_asm,
10503*67e74705SXin Li                    false))
10504*67e74705SXin Li     CmdArgs.push_back("-fverbose-asm");
10505*67e74705SXin Li 
10506*67e74705SXin Li   Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
10507*67e74705SXin Li 
10508*67e74705SXin Li   for (const auto &II : Inputs)
10509*67e74705SXin Li     CmdArgs.push_back(II.getFilename());
10510*67e74705SXin Li 
10511*67e74705SXin Li   const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("xcc"));
10512*67e74705SXin Li   C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
10513*67e74705SXin Li }
10514*67e74705SXin Li 
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const10515*67e74705SXin Li void XCore::Linker::ConstructJob(Compilation &C, const JobAction &JA,
10516*67e74705SXin Li                                  const InputInfo &Output,
10517*67e74705SXin Li                                  const InputInfoList &Inputs,
10518*67e74705SXin Li                                  const ArgList &Args,
10519*67e74705SXin Li                                  const char *LinkingOutput) const {
10520*67e74705SXin Li   ArgStringList CmdArgs;
10521*67e74705SXin Li 
10522*67e74705SXin Li   if (Output.isFilename()) {
10523*67e74705SXin Li     CmdArgs.push_back("-o");
10524*67e74705SXin Li     CmdArgs.push_back(Output.getFilename());
10525*67e74705SXin Li   } else {
10526*67e74705SXin Li     assert(Output.isNothing() && "Invalid output.");
10527*67e74705SXin Li   }
10528*67e74705SXin Li 
10529*67e74705SXin Li   if (Args.hasArg(options::OPT_v))
10530*67e74705SXin Li     CmdArgs.push_back("-v");
10531*67e74705SXin Li 
10532*67e74705SXin Li   // Pass -fexceptions through to the linker if it was present.
10533*67e74705SXin Li   if (Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions,
10534*67e74705SXin Li                    false))
10535*67e74705SXin Li     CmdArgs.push_back("-fexceptions");
10536*67e74705SXin Li 
10537*67e74705SXin Li   AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
10538*67e74705SXin Li 
10539*67e74705SXin Li   const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("xcc"));
10540*67e74705SXin Li   C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
10541*67e74705SXin Li }
10542*67e74705SXin Li 
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const10543*67e74705SXin Li void CrossWindows::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
10544*67e74705SXin Li                                            const InputInfo &Output,
10545*67e74705SXin Li                                            const InputInfoList &Inputs,
10546*67e74705SXin Li                                            const ArgList &Args,
10547*67e74705SXin Li                                            const char *LinkingOutput) const {
10548*67e74705SXin Li   claimNoWarnArgs(Args);
10549*67e74705SXin Li   const auto &TC =
10550*67e74705SXin Li       static_cast<const toolchains::CrossWindowsToolChain &>(getToolChain());
10551*67e74705SXin Li   ArgStringList CmdArgs;
10552*67e74705SXin Li   const char *Exec;
10553*67e74705SXin Li 
10554*67e74705SXin Li   switch (TC.getArch()) {
10555*67e74705SXin Li   default:
10556*67e74705SXin Li     llvm_unreachable("unsupported architecture");
10557*67e74705SXin Li   case llvm::Triple::arm:
10558*67e74705SXin Li   case llvm::Triple::thumb:
10559*67e74705SXin Li     break;
10560*67e74705SXin Li   case llvm::Triple::x86:
10561*67e74705SXin Li     CmdArgs.push_back("--32");
10562*67e74705SXin Li     break;
10563*67e74705SXin Li   case llvm::Triple::x86_64:
10564*67e74705SXin Li     CmdArgs.push_back("--64");
10565*67e74705SXin Li     break;
10566*67e74705SXin Li   }
10567*67e74705SXin Li 
10568*67e74705SXin Li   Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
10569*67e74705SXin Li 
10570*67e74705SXin Li   CmdArgs.push_back("-o");
10571*67e74705SXin Li   CmdArgs.push_back(Output.getFilename());
10572*67e74705SXin Li 
10573*67e74705SXin Li   for (const auto &Input : Inputs)
10574*67e74705SXin Li     CmdArgs.push_back(Input.getFilename());
10575*67e74705SXin Li 
10576*67e74705SXin Li   const std::string Assembler = TC.GetProgramPath("as");
10577*67e74705SXin Li   Exec = Args.MakeArgString(Assembler);
10578*67e74705SXin Li 
10579*67e74705SXin Li   C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
10580*67e74705SXin Li }
10581*67e74705SXin Li 
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const10582*67e74705SXin Li void CrossWindows::Linker::ConstructJob(Compilation &C, const JobAction &JA,
10583*67e74705SXin Li                                         const InputInfo &Output,
10584*67e74705SXin Li                                         const InputInfoList &Inputs,
10585*67e74705SXin Li                                         const ArgList &Args,
10586*67e74705SXin Li                                         const char *LinkingOutput) const {
10587*67e74705SXin Li   const auto &TC =
10588*67e74705SXin Li       static_cast<const toolchains::CrossWindowsToolChain &>(getToolChain());
10589*67e74705SXin Li   const llvm::Triple &T = TC.getTriple();
10590*67e74705SXin Li   const Driver &D = TC.getDriver();
10591*67e74705SXin Li   SmallString<128> EntryPoint;
10592*67e74705SXin Li   ArgStringList CmdArgs;
10593*67e74705SXin Li   const char *Exec;
10594*67e74705SXin Li 
10595*67e74705SXin Li   // Silence warning for "clang -g foo.o -o foo"
10596*67e74705SXin Li   Args.ClaimAllArgs(options::OPT_g_Group);
10597*67e74705SXin Li   // and "clang -emit-llvm foo.o -o foo"
10598*67e74705SXin Li   Args.ClaimAllArgs(options::OPT_emit_llvm);
10599*67e74705SXin Li   // and for "clang -w foo.o -o foo"
10600*67e74705SXin Li   Args.ClaimAllArgs(options::OPT_w);
10601*67e74705SXin Li   // Other warning options are already handled somewhere else.
10602*67e74705SXin Li 
10603*67e74705SXin Li   if (!D.SysRoot.empty())
10604*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
10605*67e74705SXin Li 
10606*67e74705SXin Li   if (Args.hasArg(options::OPT_pie))
10607*67e74705SXin Li     CmdArgs.push_back("-pie");
10608*67e74705SXin Li   if (Args.hasArg(options::OPT_rdynamic))
10609*67e74705SXin Li     CmdArgs.push_back("-export-dynamic");
10610*67e74705SXin Li   if (Args.hasArg(options::OPT_s))
10611*67e74705SXin Li     CmdArgs.push_back("--strip-all");
10612*67e74705SXin Li 
10613*67e74705SXin Li   CmdArgs.push_back("-m");
10614*67e74705SXin Li   switch (TC.getArch()) {
10615*67e74705SXin Li   default:
10616*67e74705SXin Li     llvm_unreachable("unsupported architecture");
10617*67e74705SXin Li   case llvm::Triple::arm:
10618*67e74705SXin Li   case llvm::Triple::thumb:
10619*67e74705SXin Li     // FIXME: this is incorrect for WinCE
10620*67e74705SXin Li     CmdArgs.push_back("thumb2pe");
10621*67e74705SXin Li     break;
10622*67e74705SXin Li   case llvm::Triple::x86:
10623*67e74705SXin Li     CmdArgs.push_back("i386pe");
10624*67e74705SXin Li     EntryPoint.append("_");
10625*67e74705SXin Li     break;
10626*67e74705SXin Li   case llvm::Triple::x86_64:
10627*67e74705SXin Li     CmdArgs.push_back("i386pep");
10628*67e74705SXin Li     break;
10629*67e74705SXin Li   }
10630*67e74705SXin Li 
10631*67e74705SXin Li   if (Args.hasArg(options::OPT_shared)) {
10632*67e74705SXin Li     switch (T.getArch()) {
10633*67e74705SXin Li     default:
10634*67e74705SXin Li       llvm_unreachable("unsupported architecture");
10635*67e74705SXin Li     case llvm::Triple::arm:
10636*67e74705SXin Li     case llvm::Triple::thumb:
10637*67e74705SXin Li     case llvm::Triple::x86_64:
10638*67e74705SXin Li       EntryPoint.append("_DllMainCRTStartup");
10639*67e74705SXin Li       break;
10640*67e74705SXin Li     case llvm::Triple::x86:
10641*67e74705SXin Li       EntryPoint.append("_DllMainCRTStartup@12");
10642*67e74705SXin Li       break;
10643*67e74705SXin Li     }
10644*67e74705SXin Li 
10645*67e74705SXin Li     CmdArgs.push_back("-shared");
10646*67e74705SXin Li     CmdArgs.push_back("-Bdynamic");
10647*67e74705SXin Li 
10648*67e74705SXin Li     CmdArgs.push_back("--enable-auto-image-base");
10649*67e74705SXin Li 
10650*67e74705SXin Li     CmdArgs.push_back("--entry");
10651*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(EntryPoint));
10652*67e74705SXin Li   } else {
10653*67e74705SXin Li     EntryPoint.append("mainCRTStartup");
10654*67e74705SXin Li 
10655*67e74705SXin Li     CmdArgs.push_back(Args.hasArg(options::OPT_static) ? "-Bstatic"
10656*67e74705SXin Li                                                        : "-Bdynamic");
10657*67e74705SXin Li 
10658*67e74705SXin Li     if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
10659*67e74705SXin Li       CmdArgs.push_back("--entry");
10660*67e74705SXin Li       CmdArgs.push_back(Args.MakeArgString(EntryPoint));
10661*67e74705SXin Li     }
10662*67e74705SXin Li 
10663*67e74705SXin Li     // FIXME: handle subsystem
10664*67e74705SXin Li   }
10665*67e74705SXin Li 
10666*67e74705SXin Li   // NOTE: deal with multiple definitions on Windows (e.g. COMDAT)
10667*67e74705SXin Li   CmdArgs.push_back("--allow-multiple-definition");
10668*67e74705SXin Li 
10669*67e74705SXin Li   CmdArgs.push_back("-o");
10670*67e74705SXin Li   CmdArgs.push_back(Output.getFilename());
10671*67e74705SXin Li 
10672*67e74705SXin Li   if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_rdynamic)) {
10673*67e74705SXin Li     SmallString<261> ImpLib(Output.getFilename());
10674*67e74705SXin Li     llvm::sys::path::replace_extension(ImpLib, ".lib");
10675*67e74705SXin Li 
10676*67e74705SXin Li     CmdArgs.push_back("--out-implib");
10677*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(ImpLib));
10678*67e74705SXin Li   }
10679*67e74705SXin Li 
10680*67e74705SXin Li   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
10681*67e74705SXin Li     const std::string CRTPath(D.SysRoot + "/usr/lib/");
10682*67e74705SXin Li     const char *CRTBegin;
10683*67e74705SXin Li 
10684*67e74705SXin Li     CRTBegin =
10685*67e74705SXin Li         Args.hasArg(options::OPT_shared) ? "crtbeginS.obj" : "crtbegin.obj";
10686*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(CRTPath + CRTBegin));
10687*67e74705SXin Li   }
10688*67e74705SXin Li 
10689*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_L);
10690*67e74705SXin Li   TC.AddFilePathLibArgs(Args, CmdArgs);
10691*67e74705SXin Li   AddLinkerInputs(TC, Inputs, Args, CmdArgs);
10692*67e74705SXin Li 
10693*67e74705SXin Li   if (D.CCCIsCXX() && !Args.hasArg(options::OPT_nostdlib) &&
10694*67e74705SXin Li       !Args.hasArg(options::OPT_nodefaultlibs)) {
10695*67e74705SXin Li     bool StaticCXX = Args.hasArg(options::OPT_static_libstdcxx) &&
10696*67e74705SXin Li                      !Args.hasArg(options::OPT_static);
10697*67e74705SXin Li     if (StaticCXX)
10698*67e74705SXin Li       CmdArgs.push_back("-Bstatic");
10699*67e74705SXin Li     TC.AddCXXStdlibLibArgs(Args, CmdArgs);
10700*67e74705SXin Li     if (StaticCXX)
10701*67e74705SXin Li       CmdArgs.push_back("-Bdynamic");
10702*67e74705SXin Li   }
10703*67e74705SXin Li 
10704*67e74705SXin Li   if (!Args.hasArg(options::OPT_nostdlib)) {
10705*67e74705SXin Li     if (!Args.hasArg(options::OPT_nodefaultlibs)) {
10706*67e74705SXin Li       // TODO handle /MT[d] /MD[d]
10707*67e74705SXin Li       CmdArgs.push_back("-lmsvcrt");
10708*67e74705SXin Li       AddRunTimeLibs(TC, D, CmdArgs, Args);
10709*67e74705SXin Li     }
10710*67e74705SXin Li   }
10711*67e74705SXin Li 
10712*67e74705SXin Li   if (TC.getSanitizerArgs().needsAsanRt()) {
10713*67e74705SXin Li     // TODO handle /MT[d] /MD[d]
10714*67e74705SXin Li     if (Args.hasArg(options::OPT_shared)) {
10715*67e74705SXin Li       CmdArgs.push_back(TC.getCompilerRTArgString(Args, "asan_dll_thunk"));
10716*67e74705SXin Li     } else {
10717*67e74705SXin Li       for (const auto &Lib : {"asan_dynamic", "asan_dynamic_runtime_thunk"})
10718*67e74705SXin Li         CmdArgs.push_back(TC.getCompilerRTArgString(Args, Lib));
10719*67e74705SXin Li       // Make sure the dynamic runtime thunk is not optimized out at link time
10720*67e74705SXin Li       // to ensure proper SEH handling.
10721*67e74705SXin Li       CmdArgs.push_back(Args.MakeArgString("--undefined"));
10722*67e74705SXin Li       CmdArgs.push_back(Args.MakeArgString(TC.getArch() == llvm::Triple::x86
10723*67e74705SXin Li                                                ? "___asan_seh_interceptor"
10724*67e74705SXin Li                                                : "__asan_seh_interceptor"));
10725*67e74705SXin Li     }
10726*67e74705SXin Li   }
10727*67e74705SXin Li 
10728*67e74705SXin Li   Exec = Args.MakeArgString(TC.GetLinkerPath());
10729*67e74705SXin Li 
10730*67e74705SXin Li   C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
10731*67e74705SXin Li }
10732*67e74705SXin Li 
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const10733*67e74705SXin Li void tools::SHAVE::Compiler::ConstructJob(Compilation &C, const JobAction &JA,
10734*67e74705SXin Li                                           const InputInfo &Output,
10735*67e74705SXin Li                                           const InputInfoList &Inputs,
10736*67e74705SXin Li                                           const ArgList &Args,
10737*67e74705SXin Li                                           const char *LinkingOutput) const {
10738*67e74705SXin Li   ArgStringList CmdArgs;
10739*67e74705SXin Li   assert(Inputs.size() == 1);
10740*67e74705SXin Li   const InputInfo &II = Inputs[0];
10741*67e74705SXin Li   assert(II.getType() == types::TY_C || II.getType() == types::TY_CXX ||
10742*67e74705SXin Li          II.getType() == types::TY_PP_CXX);
10743*67e74705SXin Li 
10744*67e74705SXin Li   if (JA.getKind() == Action::PreprocessJobClass) {
10745*67e74705SXin Li     Args.ClaimAllArgs();
10746*67e74705SXin Li     CmdArgs.push_back("-E");
10747*67e74705SXin Li   } else {
10748*67e74705SXin Li     assert(Output.getType() == types::TY_PP_Asm); // Require preprocessed asm.
10749*67e74705SXin Li     CmdArgs.push_back("-S");
10750*67e74705SXin Li     CmdArgs.push_back("-fno-exceptions"); // Always do this even if unspecified.
10751*67e74705SXin Li   }
10752*67e74705SXin Li   CmdArgs.push_back("-DMYRIAD2");
10753*67e74705SXin Li 
10754*67e74705SXin Li   // Append all -I, -iquote, -isystem paths, defines/undefines,
10755*67e74705SXin Li   // 'f' flags, optimize flags, and warning options.
10756*67e74705SXin Li   // These are spelled the same way in clang and moviCompile.
10757*67e74705SXin Li   Args.AddAllArgs(CmdArgs, {options::OPT_I_Group, options::OPT_clang_i_Group,
10758*67e74705SXin Li                             options::OPT_std_EQ, options::OPT_D, options::OPT_U,
10759*67e74705SXin Li                             options::OPT_f_Group, options::OPT_f_clang_Group,
10760*67e74705SXin Li                             options::OPT_g_Group, options::OPT_M_Group,
10761*67e74705SXin Li                             options::OPT_O_Group, options::OPT_W_Group,
10762*67e74705SXin Li                             options::OPT_mcpu_EQ});
10763*67e74705SXin Li 
10764*67e74705SXin Li   // If we're producing a dependency file, and assembly is the final action,
10765*67e74705SXin Li   // then the name of the target in the dependency file should be the '.o'
10766*67e74705SXin Li   // file, not the '.s' file produced by this step. For example, instead of
10767*67e74705SXin Li   //  /tmp/mumble.s: mumble.c .../someheader.h
10768*67e74705SXin Li   // the filename on the lefthand side should be "mumble.o"
10769*67e74705SXin Li   if (Args.getLastArg(options::OPT_MF) && !Args.getLastArg(options::OPT_MT) &&
10770*67e74705SXin Li       C.getActions().size() == 1 &&
10771*67e74705SXin Li       C.getActions()[0]->getKind() == Action::AssembleJobClass) {
10772*67e74705SXin Li     Arg *A = Args.getLastArg(options::OPT_o);
10773*67e74705SXin Li     if (A) {
10774*67e74705SXin Li       CmdArgs.push_back("-MT");
10775*67e74705SXin Li       CmdArgs.push_back(Args.MakeArgString(A->getValue()));
10776*67e74705SXin Li     }
10777*67e74705SXin Li   }
10778*67e74705SXin Li 
10779*67e74705SXin Li   CmdArgs.push_back(II.getFilename());
10780*67e74705SXin Li   CmdArgs.push_back("-o");
10781*67e74705SXin Li   CmdArgs.push_back(Output.getFilename());
10782*67e74705SXin Li 
10783*67e74705SXin Li   std::string Exec =
10784*67e74705SXin Li       Args.MakeArgString(getToolChain().GetProgramPath("moviCompile"));
10785*67e74705SXin Li   C.addCommand(llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Exec),
10786*67e74705SXin Li                                           CmdArgs, Inputs));
10787*67e74705SXin Li }
10788*67e74705SXin Li 
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const10789*67e74705SXin Li void tools::SHAVE::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
10790*67e74705SXin Li                                            const InputInfo &Output,
10791*67e74705SXin Li                                            const InputInfoList &Inputs,
10792*67e74705SXin Li                                            const ArgList &Args,
10793*67e74705SXin Li                                            const char *LinkingOutput) const {
10794*67e74705SXin Li   ArgStringList CmdArgs;
10795*67e74705SXin Li 
10796*67e74705SXin Li   assert(Inputs.size() == 1);
10797*67e74705SXin Li   const InputInfo &II = Inputs[0];
10798*67e74705SXin Li   assert(II.getType() == types::TY_PP_Asm); // Require preprocessed asm input.
10799*67e74705SXin Li   assert(Output.getType() == types::TY_Object);
10800*67e74705SXin Li 
10801*67e74705SXin Li   CmdArgs.push_back("-no6thSlotCompression");
10802*67e74705SXin Li   const Arg *CPUArg = Args.getLastArg(options::OPT_mcpu_EQ);
10803*67e74705SXin Li   if (CPUArg)
10804*67e74705SXin Li     CmdArgs.push_back(
10805*67e74705SXin Li         Args.MakeArgString("-cv:" + StringRef(CPUArg->getValue())));
10806*67e74705SXin Li   CmdArgs.push_back("-noSPrefixing");
10807*67e74705SXin Li   CmdArgs.push_back("-a"); // Mystery option.
10808*67e74705SXin Li   Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
10809*67e74705SXin Li   for (const Arg *A : Args.filtered(options::OPT_I, options::OPT_isystem)) {
10810*67e74705SXin Li     A->claim();
10811*67e74705SXin Li     CmdArgs.push_back(
10812*67e74705SXin Li         Args.MakeArgString(std::string("-i:") + A->getValue(0)));
10813*67e74705SXin Li   }
10814*67e74705SXin Li   CmdArgs.push_back("-elf"); // Output format.
10815*67e74705SXin Li   CmdArgs.push_back(II.getFilename());
10816*67e74705SXin Li   CmdArgs.push_back(
10817*67e74705SXin Li       Args.MakeArgString(std::string("-o:") + Output.getFilename()));
10818*67e74705SXin Li 
10819*67e74705SXin Li   std::string Exec =
10820*67e74705SXin Li       Args.MakeArgString(getToolChain().GetProgramPath("moviAsm"));
10821*67e74705SXin Li   C.addCommand(llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Exec),
10822*67e74705SXin Li                                           CmdArgs, Inputs));
10823*67e74705SXin Li }
10824*67e74705SXin Li 
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const10825*67e74705SXin Li void tools::Myriad::Linker::ConstructJob(Compilation &C, const JobAction &JA,
10826*67e74705SXin Li                                          const InputInfo &Output,
10827*67e74705SXin Li                                          const InputInfoList &Inputs,
10828*67e74705SXin Li                                          const ArgList &Args,
10829*67e74705SXin Li                                          const char *LinkingOutput) const {
10830*67e74705SXin Li   const auto &TC =
10831*67e74705SXin Li       static_cast<const toolchains::MyriadToolChain &>(getToolChain());
10832*67e74705SXin Li   const llvm::Triple &T = TC.getTriple();
10833*67e74705SXin Li   ArgStringList CmdArgs;
10834*67e74705SXin Li   bool UseStartfiles =
10835*67e74705SXin Li       !Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles);
10836*67e74705SXin Li   bool UseDefaultLibs =
10837*67e74705SXin Li       !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs);
10838*67e74705SXin Li 
10839*67e74705SXin Li   if (T.getArch() == llvm::Triple::sparc)
10840*67e74705SXin Li     CmdArgs.push_back("-EB");
10841*67e74705SXin Li   else // SHAVE assumes little-endian, and sparcel is expressly so.
10842*67e74705SXin Li     CmdArgs.push_back("-EL");
10843*67e74705SXin Li 
10844*67e74705SXin Li   // The remaining logic is mostly like gnutools::Linker::ConstructJob,
10845*67e74705SXin Li   // but we never pass through a --sysroot option and various other bits.
10846*67e74705SXin Li   // For example, there are no sanitizers (yet) nor gold linker.
10847*67e74705SXin Li 
10848*67e74705SXin Li   // Eat some arguments that may be present but have no effect.
10849*67e74705SXin Li   Args.ClaimAllArgs(options::OPT_g_Group);
10850*67e74705SXin Li   Args.ClaimAllArgs(options::OPT_w);
10851*67e74705SXin Li   Args.ClaimAllArgs(options::OPT_static_libgcc);
10852*67e74705SXin Li 
10853*67e74705SXin Li   if (Args.hasArg(options::OPT_s)) // Pass the 'strip' option.
10854*67e74705SXin Li     CmdArgs.push_back("-s");
10855*67e74705SXin Li 
10856*67e74705SXin Li   CmdArgs.push_back("-o");
10857*67e74705SXin Li   CmdArgs.push_back(Output.getFilename());
10858*67e74705SXin Li 
10859*67e74705SXin Li   if (UseStartfiles) {
10860*67e74705SXin Li     // If you want startfiles, it means you want the builtin crti and crtbegin,
10861*67e74705SXin Li     // but not crt0. Myriad link commands provide their own crt0.o as needed.
10862*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crti.o")));
10863*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crtbegin.o")));
10864*67e74705SXin Li   }
10865*67e74705SXin Li 
10866*67e74705SXin Li   Args.AddAllArgs(CmdArgs, {options::OPT_L, options::OPT_T_Group,
10867*67e74705SXin Li                             options::OPT_e, options::OPT_s, options::OPT_t,
10868*67e74705SXin Li                             options::OPT_Z_Flag, options::OPT_r});
10869*67e74705SXin Li 
10870*67e74705SXin Li   TC.AddFilePathLibArgs(Args, CmdArgs);
10871*67e74705SXin Li 
10872*67e74705SXin Li   AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
10873*67e74705SXin Li 
10874*67e74705SXin Li   if (UseDefaultLibs) {
10875*67e74705SXin Li     if (C.getDriver().CCCIsCXX())
10876*67e74705SXin Li       CmdArgs.push_back("-lstdc++");
10877*67e74705SXin Li     if (T.getOS() == llvm::Triple::RTEMS) {
10878*67e74705SXin Li       CmdArgs.push_back("--start-group");
10879*67e74705SXin Li       CmdArgs.push_back("-lc");
10880*67e74705SXin Li       // You must provide your own "-L" option to enable finding these.
10881*67e74705SXin Li       CmdArgs.push_back("-lrtemscpu");
10882*67e74705SXin Li       CmdArgs.push_back("-lrtemsbsp");
10883*67e74705SXin Li       CmdArgs.push_back("--end-group");
10884*67e74705SXin Li     } else {
10885*67e74705SXin Li       CmdArgs.push_back("-lc");
10886*67e74705SXin Li     }
10887*67e74705SXin Li     CmdArgs.push_back("-lgcc");
10888*67e74705SXin Li   }
10889*67e74705SXin Li   if (UseStartfiles) {
10890*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crtend.o")));
10891*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crtn.o")));
10892*67e74705SXin Li   }
10893*67e74705SXin Li 
10894*67e74705SXin Li   std::string Exec =
10895*67e74705SXin Li       Args.MakeArgString(TC.GetProgramPath("sparc-myriad-elf-ld"));
10896*67e74705SXin Li   C.addCommand(llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Exec),
10897*67e74705SXin Li                                           CmdArgs, Inputs));
10898*67e74705SXin Li }
10899*67e74705SXin Li 
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const10900*67e74705SXin Li void PS4cpu::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
10901*67e74705SXin Li                                     const InputInfo &Output,
10902*67e74705SXin Li                                     const InputInfoList &Inputs,
10903*67e74705SXin Li                                     const ArgList &Args,
10904*67e74705SXin Li                                     const char *LinkingOutput) const {
10905*67e74705SXin Li   claimNoWarnArgs(Args);
10906*67e74705SXin Li   ArgStringList CmdArgs;
10907*67e74705SXin Li 
10908*67e74705SXin Li   Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
10909*67e74705SXin Li 
10910*67e74705SXin Li   CmdArgs.push_back("-o");
10911*67e74705SXin Li   CmdArgs.push_back(Output.getFilename());
10912*67e74705SXin Li 
10913*67e74705SXin Li   assert(Inputs.size() == 1 && "Unexpected number of inputs.");
10914*67e74705SXin Li   const InputInfo &Input = Inputs[0];
10915*67e74705SXin Li   assert(Input.isFilename() && "Invalid input.");
10916*67e74705SXin Li   CmdArgs.push_back(Input.getFilename());
10917*67e74705SXin Li 
10918*67e74705SXin Li   const char *Exec =
10919*67e74705SXin Li       Args.MakeArgString(getToolChain().GetProgramPath("orbis-as"));
10920*67e74705SXin Li   C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
10921*67e74705SXin Li }
10922*67e74705SXin Li 
AddPS4SanitizerArgs(const ToolChain & TC,ArgStringList & CmdArgs)10923*67e74705SXin Li static void AddPS4SanitizerArgs(const ToolChain &TC, ArgStringList &CmdArgs) {
10924*67e74705SXin Li   const SanitizerArgs &SanArgs = TC.getSanitizerArgs();
10925*67e74705SXin Li   if (SanArgs.needsUbsanRt()) {
10926*67e74705SXin Li     CmdArgs.push_back("-lSceDbgUBSanitizer_stub_weak");
10927*67e74705SXin Li   }
10928*67e74705SXin Li   if (SanArgs.needsAsanRt()) {
10929*67e74705SXin Li     CmdArgs.push_back("-lSceDbgAddressSanitizer_stub_weak");
10930*67e74705SXin Li   }
10931*67e74705SXin Li }
10932*67e74705SXin Li 
ConstructPS4LinkJob(const Tool & T,Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput)10933*67e74705SXin Li static void ConstructPS4LinkJob(const Tool &T, Compilation &C,
10934*67e74705SXin Li                                 const JobAction &JA, const InputInfo &Output,
10935*67e74705SXin Li                                 const InputInfoList &Inputs,
10936*67e74705SXin Li                                 const ArgList &Args,
10937*67e74705SXin Li                                 const char *LinkingOutput) {
10938*67e74705SXin Li   const toolchains::FreeBSD &ToolChain =
10939*67e74705SXin Li       static_cast<const toolchains::FreeBSD &>(T.getToolChain());
10940*67e74705SXin Li   const Driver &D = ToolChain.getDriver();
10941*67e74705SXin Li   ArgStringList CmdArgs;
10942*67e74705SXin Li 
10943*67e74705SXin Li   // Silence warning for "clang -g foo.o -o foo"
10944*67e74705SXin Li   Args.ClaimAllArgs(options::OPT_g_Group);
10945*67e74705SXin Li   // and "clang -emit-llvm foo.o -o foo"
10946*67e74705SXin Li   Args.ClaimAllArgs(options::OPT_emit_llvm);
10947*67e74705SXin Li   // and for "clang -w foo.o -o foo". Other warning options are already
10948*67e74705SXin Li   // handled somewhere else.
10949*67e74705SXin Li   Args.ClaimAllArgs(options::OPT_w);
10950*67e74705SXin Li 
10951*67e74705SXin Li   if (!D.SysRoot.empty())
10952*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
10953*67e74705SXin Li 
10954*67e74705SXin Li   if (Args.hasArg(options::OPT_pie))
10955*67e74705SXin Li     CmdArgs.push_back("-pie");
10956*67e74705SXin Li 
10957*67e74705SXin Li   if (Args.hasArg(options::OPT_rdynamic))
10958*67e74705SXin Li     CmdArgs.push_back("-export-dynamic");
10959*67e74705SXin Li   if (Args.hasArg(options::OPT_shared))
10960*67e74705SXin Li     CmdArgs.push_back("--oformat=so");
10961*67e74705SXin Li 
10962*67e74705SXin Li   if (Output.isFilename()) {
10963*67e74705SXin Li     CmdArgs.push_back("-o");
10964*67e74705SXin Li     CmdArgs.push_back(Output.getFilename());
10965*67e74705SXin Li   } else {
10966*67e74705SXin Li     assert(Output.isNothing() && "Invalid output.");
10967*67e74705SXin Li   }
10968*67e74705SXin Li 
10969*67e74705SXin Li   AddPS4SanitizerArgs(ToolChain, CmdArgs);
10970*67e74705SXin Li 
10971*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_L);
10972*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
10973*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_e);
10974*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_s);
10975*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_t);
10976*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_r);
10977*67e74705SXin Li 
10978*67e74705SXin Li   if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
10979*67e74705SXin Li     CmdArgs.push_back("--no-demangle");
10980*67e74705SXin Li 
10981*67e74705SXin Li   AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
10982*67e74705SXin Li 
10983*67e74705SXin Li   if (Args.hasArg(options::OPT_pthread)) {
10984*67e74705SXin Li     CmdArgs.push_back("-lpthread");
10985*67e74705SXin Li   }
10986*67e74705SXin Li 
10987*67e74705SXin Li   const char *Exec = Args.MakeArgString(ToolChain.GetProgramPath("orbis-ld"));
10988*67e74705SXin Li 
10989*67e74705SXin Li   C.addCommand(llvm::make_unique<Command>(JA, T, Exec, CmdArgs, Inputs));
10990*67e74705SXin Li }
10991*67e74705SXin Li 
ConstructGoldLinkJob(const Tool & T,Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput)10992*67e74705SXin Li static void ConstructGoldLinkJob(const Tool &T, Compilation &C,
10993*67e74705SXin Li                                  const JobAction &JA, const InputInfo &Output,
10994*67e74705SXin Li                                  const InputInfoList &Inputs,
10995*67e74705SXin Li                                  const ArgList &Args,
10996*67e74705SXin Li                                  const char *LinkingOutput) {
10997*67e74705SXin Li   const toolchains::FreeBSD &ToolChain =
10998*67e74705SXin Li       static_cast<const toolchains::FreeBSD &>(T.getToolChain());
10999*67e74705SXin Li   const Driver &D = ToolChain.getDriver();
11000*67e74705SXin Li   ArgStringList CmdArgs;
11001*67e74705SXin Li 
11002*67e74705SXin Li   // Silence warning for "clang -g foo.o -o foo"
11003*67e74705SXin Li   Args.ClaimAllArgs(options::OPT_g_Group);
11004*67e74705SXin Li   // and "clang -emit-llvm foo.o -o foo"
11005*67e74705SXin Li   Args.ClaimAllArgs(options::OPT_emit_llvm);
11006*67e74705SXin Li   // and for "clang -w foo.o -o foo". Other warning options are already
11007*67e74705SXin Li   // handled somewhere else.
11008*67e74705SXin Li   Args.ClaimAllArgs(options::OPT_w);
11009*67e74705SXin Li 
11010*67e74705SXin Li   if (!D.SysRoot.empty())
11011*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
11012*67e74705SXin Li 
11013*67e74705SXin Li   if (Args.hasArg(options::OPT_pie))
11014*67e74705SXin Li     CmdArgs.push_back("-pie");
11015*67e74705SXin Li 
11016*67e74705SXin Li   if (Args.hasArg(options::OPT_static)) {
11017*67e74705SXin Li     CmdArgs.push_back("-Bstatic");
11018*67e74705SXin Li   } else {
11019*67e74705SXin Li     if (Args.hasArg(options::OPT_rdynamic))
11020*67e74705SXin Li       CmdArgs.push_back("-export-dynamic");
11021*67e74705SXin Li     CmdArgs.push_back("--eh-frame-hdr");
11022*67e74705SXin Li     if (Args.hasArg(options::OPT_shared)) {
11023*67e74705SXin Li       CmdArgs.push_back("-Bshareable");
11024*67e74705SXin Li     } else {
11025*67e74705SXin Li       CmdArgs.push_back("-dynamic-linker");
11026*67e74705SXin Li       CmdArgs.push_back("/libexec/ld-elf.so.1");
11027*67e74705SXin Li     }
11028*67e74705SXin Li     CmdArgs.push_back("--enable-new-dtags");
11029*67e74705SXin Li   }
11030*67e74705SXin Li 
11031*67e74705SXin Li   if (Output.isFilename()) {
11032*67e74705SXin Li     CmdArgs.push_back("-o");
11033*67e74705SXin Li     CmdArgs.push_back(Output.getFilename());
11034*67e74705SXin Li   } else {
11035*67e74705SXin Li     assert(Output.isNothing() && "Invalid output.");
11036*67e74705SXin Li   }
11037*67e74705SXin Li 
11038*67e74705SXin Li   AddPS4SanitizerArgs(ToolChain, CmdArgs);
11039*67e74705SXin Li 
11040*67e74705SXin Li   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
11041*67e74705SXin Li     const char *crt1 = nullptr;
11042*67e74705SXin Li     if (!Args.hasArg(options::OPT_shared)) {
11043*67e74705SXin Li       if (Args.hasArg(options::OPT_pg))
11044*67e74705SXin Li         crt1 = "gcrt1.o";
11045*67e74705SXin Li       else if (Args.hasArg(options::OPT_pie))
11046*67e74705SXin Li         crt1 = "Scrt1.o";
11047*67e74705SXin Li       else
11048*67e74705SXin Li         crt1 = "crt1.o";
11049*67e74705SXin Li     }
11050*67e74705SXin Li     if (crt1)
11051*67e74705SXin Li       CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crt1)));
11052*67e74705SXin Li 
11053*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o")));
11054*67e74705SXin Li 
11055*67e74705SXin Li     const char *crtbegin = nullptr;
11056*67e74705SXin Li     if (Args.hasArg(options::OPT_static))
11057*67e74705SXin Li       crtbegin = "crtbeginT.o";
11058*67e74705SXin Li     else if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
11059*67e74705SXin Li       crtbegin = "crtbeginS.o";
11060*67e74705SXin Li     else
11061*67e74705SXin Li       crtbegin = "crtbegin.o";
11062*67e74705SXin Li 
11063*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin)));
11064*67e74705SXin Li   }
11065*67e74705SXin Li 
11066*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_L);
11067*67e74705SXin Li   ToolChain.AddFilePathLibArgs(Args, CmdArgs);
11068*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
11069*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_e);
11070*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_s);
11071*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_t);
11072*67e74705SXin Li   Args.AddAllArgs(CmdArgs, options::OPT_r);
11073*67e74705SXin Li 
11074*67e74705SXin Li   if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
11075*67e74705SXin Li     CmdArgs.push_back("--no-demangle");
11076*67e74705SXin Li 
11077*67e74705SXin Li   AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
11078*67e74705SXin Li 
11079*67e74705SXin Li   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
11080*67e74705SXin Li     // For PS4, we always want to pass libm, libstdc++ and libkernel
11081*67e74705SXin Li     // libraries for both C and C++ compilations.
11082*67e74705SXin Li     CmdArgs.push_back("-lkernel");
11083*67e74705SXin Li     if (D.CCCIsCXX()) {
11084*67e74705SXin Li       ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
11085*67e74705SXin Li       if (Args.hasArg(options::OPT_pg))
11086*67e74705SXin Li         CmdArgs.push_back("-lm_p");
11087*67e74705SXin Li       else
11088*67e74705SXin Li         CmdArgs.push_back("-lm");
11089*67e74705SXin Li     }
11090*67e74705SXin Li     // FIXME: For some reason GCC passes -lgcc and -lgcc_s before adding
11091*67e74705SXin Li     // the default system libraries. Just mimic this for now.
11092*67e74705SXin Li     if (Args.hasArg(options::OPT_pg))
11093*67e74705SXin Li       CmdArgs.push_back("-lgcc_p");
11094*67e74705SXin Li     else
11095*67e74705SXin Li       CmdArgs.push_back("-lcompiler_rt");
11096*67e74705SXin Li     if (Args.hasArg(options::OPT_static)) {
11097*67e74705SXin Li       CmdArgs.push_back("-lstdc++");
11098*67e74705SXin Li     } else if (Args.hasArg(options::OPT_pg)) {
11099*67e74705SXin Li       CmdArgs.push_back("-lgcc_eh_p");
11100*67e74705SXin Li     } else {
11101*67e74705SXin Li       CmdArgs.push_back("--as-needed");
11102*67e74705SXin Li       CmdArgs.push_back("-lstdc++");
11103*67e74705SXin Li       CmdArgs.push_back("--no-as-needed");
11104*67e74705SXin Li     }
11105*67e74705SXin Li 
11106*67e74705SXin Li     if (Args.hasArg(options::OPT_pthread)) {
11107*67e74705SXin Li       if (Args.hasArg(options::OPT_pg))
11108*67e74705SXin Li         CmdArgs.push_back("-lpthread_p");
11109*67e74705SXin Li       else
11110*67e74705SXin Li         CmdArgs.push_back("-lpthread");
11111*67e74705SXin Li     }
11112*67e74705SXin Li 
11113*67e74705SXin Li     if (Args.hasArg(options::OPT_pg)) {
11114*67e74705SXin Li       if (Args.hasArg(options::OPT_shared))
11115*67e74705SXin Li         CmdArgs.push_back("-lc");
11116*67e74705SXin Li       else {
11117*67e74705SXin Li         if (Args.hasArg(options::OPT_static)) {
11118*67e74705SXin Li           CmdArgs.push_back("--start-group");
11119*67e74705SXin Li           CmdArgs.push_back("-lc_p");
11120*67e74705SXin Li           CmdArgs.push_back("-lpthread_p");
11121*67e74705SXin Li           CmdArgs.push_back("--end-group");
11122*67e74705SXin Li         } else {
11123*67e74705SXin Li           CmdArgs.push_back("-lc_p");
11124*67e74705SXin Li         }
11125*67e74705SXin Li       }
11126*67e74705SXin Li       CmdArgs.push_back("-lgcc_p");
11127*67e74705SXin Li     } else {
11128*67e74705SXin Li       if (Args.hasArg(options::OPT_static)) {
11129*67e74705SXin Li         CmdArgs.push_back("--start-group");
11130*67e74705SXin Li         CmdArgs.push_back("-lc");
11131*67e74705SXin Li         CmdArgs.push_back("-lpthread");
11132*67e74705SXin Li         CmdArgs.push_back("--end-group");
11133*67e74705SXin Li       } else {
11134*67e74705SXin Li         CmdArgs.push_back("-lc");
11135*67e74705SXin Li       }
11136*67e74705SXin Li       CmdArgs.push_back("-lcompiler_rt");
11137*67e74705SXin Li     }
11138*67e74705SXin Li 
11139*67e74705SXin Li     if (Args.hasArg(options::OPT_static)) {
11140*67e74705SXin Li       CmdArgs.push_back("-lstdc++");
11141*67e74705SXin Li     } else if (Args.hasArg(options::OPT_pg)) {
11142*67e74705SXin Li       CmdArgs.push_back("-lgcc_eh_p");
11143*67e74705SXin Li     } else {
11144*67e74705SXin Li       CmdArgs.push_back("--as-needed");
11145*67e74705SXin Li       CmdArgs.push_back("-lstdc++");
11146*67e74705SXin Li       CmdArgs.push_back("--no-as-needed");
11147*67e74705SXin Li     }
11148*67e74705SXin Li   }
11149*67e74705SXin Li 
11150*67e74705SXin Li   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
11151*67e74705SXin Li     if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
11152*67e74705SXin Li       CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtendS.o")));
11153*67e74705SXin Li     else
11154*67e74705SXin Li       CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtend.o")));
11155*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o")));
11156*67e74705SXin Li   }
11157*67e74705SXin Li 
11158*67e74705SXin Li   const char *Exec =
11159*67e74705SXin Li #ifdef LLVM_ON_WIN32
11160*67e74705SXin Li       Args.MakeArgString(ToolChain.GetProgramPath("orbis-ld.gold"));
11161*67e74705SXin Li #else
11162*67e74705SXin Li       Args.MakeArgString(ToolChain.GetProgramPath("orbis-ld"));
11163*67e74705SXin Li #endif
11164*67e74705SXin Li 
11165*67e74705SXin Li   C.addCommand(llvm::make_unique<Command>(JA, T, Exec, CmdArgs, Inputs));
11166*67e74705SXin Li }
11167*67e74705SXin Li 
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const11168*67e74705SXin Li void PS4cpu::Link::ConstructJob(Compilation &C, const JobAction &JA,
11169*67e74705SXin Li                                 const InputInfo &Output,
11170*67e74705SXin Li                                 const InputInfoList &Inputs,
11171*67e74705SXin Li                                 const ArgList &Args,
11172*67e74705SXin Li                                 const char *LinkingOutput) const {
11173*67e74705SXin Li   const toolchains::FreeBSD &ToolChain =
11174*67e74705SXin Li       static_cast<const toolchains::FreeBSD &>(getToolChain());
11175*67e74705SXin Li   const Driver &D = ToolChain.getDriver();
11176*67e74705SXin Li   bool PS4Linker;
11177*67e74705SXin Li   StringRef LinkerOptName;
11178*67e74705SXin Li   if (const Arg *A = Args.getLastArg(options::OPT_fuse_ld_EQ)) {
11179*67e74705SXin Li     LinkerOptName = A->getValue();
11180*67e74705SXin Li     if (LinkerOptName != "ps4" && LinkerOptName != "gold")
11181*67e74705SXin Li       D.Diag(diag::err_drv_unsupported_linker) << LinkerOptName;
11182*67e74705SXin Li   }
11183*67e74705SXin Li 
11184*67e74705SXin Li   if (LinkerOptName == "gold")
11185*67e74705SXin Li     PS4Linker = false;
11186*67e74705SXin Li   else if (LinkerOptName == "ps4")
11187*67e74705SXin Li     PS4Linker = true;
11188*67e74705SXin Li   else
11189*67e74705SXin Li     PS4Linker = !Args.hasArg(options::OPT_shared);
11190*67e74705SXin Li 
11191*67e74705SXin Li   if (PS4Linker)
11192*67e74705SXin Li     ConstructPS4LinkJob(*this, C, JA, Output, Inputs, Args, LinkingOutput);
11193*67e74705SXin Li   else
11194*67e74705SXin Li     ConstructGoldLinkJob(*this, C, JA, Output, Inputs, Args, LinkingOutput);
11195*67e74705SXin Li }
11196*67e74705SXin Li 
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const11197*67e74705SXin Li void NVPTX::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
11198*67e74705SXin Li                                     const InputInfo &Output,
11199*67e74705SXin Li                                     const InputInfoList &Inputs,
11200*67e74705SXin Li                                     const ArgList &Args,
11201*67e74705SXin Li                                     const char *LinkingOutput) const {
11202*67e74705SXin Li   const auto &TC =
11203*67e74705SXin Li       static_cast<const toolchains::CudaToolChain &>(getToolChain());
11204*67e74705SXin Li   assert(TC.getTriple().isNVPTX() && "Wrong platform");
11205*67e74705SXin Li 
11206*67e74705SXin Li   std::vector<std::string> gpu_archs =
11207*67e74705SXin Li       Args.getAllArgValues(options::OPT_march_EQ);
11208*67e74705SXin Li   assert(gpu_archs.size() == 1 && "Exactly one GPU Arch required for ptxas.");
11209*67e74705SXin Li   const std::string& gpu_arch = gpu_archs[0];
11210*67e74705SXin Li 
11211*67e74705SXin Li   // Check that our installation's ptxas supports gpu_arch.
11212*67e74705SXin Li   if (!Args.hasArg(options::OPT_no_cuda_version_check)) {
11213*67e74705SXin Li     TC.cudaInstallation().CheckCudaVersionSupportsArch(
11214*67e74705SXin Li         StringToCudaArch(gpu_arch));
11215*67e74705SXin Li   }
11216*67e74705SXin Li 
11217*67e74705SXin Li   ArgStringList CmdArgs;
11218*67e74705SXin Li   CmdArgs.push_back(TC.getTriple().isArch64Bit() ? "-m64" : "-m32");
11219*67e74705SXin Li   if (Args.hasFlag(options::OPT_cuda_noopt_device_debug,
11220*67e74705SXin Li                    options::OPT_no_cuda_noopt_device_debug, false)) {
11221*67e74705SXin Li     // ptxas does not accept -g option if optimization is enabled, so
11222*67e74705SXin Li     // we ignore the compiler's -O* options if we want debug info.
11223*67e74705SXin Li     CmdArgs.push_back("-g");
11224*67e74705SXin Li     CmdArgs.push_back("--dont-merge-basicblocks");
11225*67e74705SXin Li     CmdArgs.push_back("--return-at-end");
11226*67e74705SXin Li   } else if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
11227*67e74705SXin Li     // Map the -O we received to -O{0,1,2,3}.
11228*67e74705SXin Li     //
11229*67e74705SXin Li     // TODO: Perhaps we should map host -O2 to ptxas -O3. -O3 is ptxas's
11230*67e74705SXin Li     // default, so it may correspond more closely to the spirit of clang -O2.
11231*67e74705SXin Li 
11232*67e74705SXin Li     // -O3 seems like the least-bad option when -Osomething is specified to
11233*67e74705SXin Li     // clang but it isn't handled below.
11234*67e74705SXin Li     StringRef OOpt = "3";
11235*67e74705SXin Li     if (A->getOption().matches(options::OPT_O4) ||
11236*67e74705SXin Li         A->getOption().matches(options::OPT_Ofast))
11237*67e74705SXin Li       OOpt = "3";
11238*67e74705SXin Li     else if (A->getOption().matches(options::OPT_O0))
11239*67e74705SXin Li       OOpt = "0";
11240*67e74705SXin Li     else if (A->getOption().matches(options::OPT_O)) {
11241*67e74705SXin Li       // -Os, -Oz, and -O(anything else) map to -O2, for lack of better options.
11242*67e74705SXin Li       OOpt = llvm::StringSwitch<const char *>(A->getValue())
11243*67e74705SXin Li                  .Case("1", "1")
11244*67e74705SXin Li                  .Case("2", "2")
11245*67e74705SXin Li                  .Case("3", "3")
11246*67e74705SXin Li                  .Case("s", "2")
11247*67e74705SXin Li                  .Case("z", "2")
11248*67e74705SXin Li                  .Default("2");
11249*67e74705SXin Li     }
11250*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(llvm::Twine("-O") + OOpt));
11251*67e74705SXin Li   } else {
11252*67e74705SXin Li     // If no -O was passed, pass -O0 to ptxas -- no opt flag should correspond
11253*67e74705SXin Li     // to no optimizations, but ptxas's default is -O3.
11254*67e74705SXin Li     CmdArgs.push_back("-O0");
11255*67e74705SXin Li   }
11256*67e74705SXin Li 
11257*67e74705SXin Li   CmdArgs.push_back("--gpu-name");
11258*67e74705SXin Li   CmdArgs.push_back(Args.MakeArgString(gpu_arch));
11259*67e74705SXin Li   CmdArgs.push_back("--output-file");
11260*67e74705SXin Li   CmdArgs.push_back(Args.MakeArgString(Output.getFilename()));
11261*67e74705SXin Li   for (const auto& II : Inputs)
11262*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(II.getFilename()));
11263*67e74705SXin Li 
11264*67e74705SXin Li   for (const auto& A : Args.getAllArgValues(options::OPT_Xcuda_ptxas))
11265*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(A));
11266*67e74705SXin Li 
11267*67e74705SXin Li   const char *Exec = Args.MakeArgString(TC.GetProgramPath("ptxas"));
11268*67e74705SXin Li   C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
11269*67e74705SXin Li }
11270*67e74705SXin Li 
11271*67e74705SXin Li // All inputs to this linker must be from CudaDeviceActions, as we need to look
11272*67e74705SXin Li // at the Inputs' Actions in order to figure out which GPU architecture they
11273*67e74705SXin Li // correspond to.
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const11274*67e74705SXin Li void NVPTX::Linker::ConstructJob(Compilation &C, const JobAction &JA,
11275*67e74705SXin Li                                  const InputInfo &Output,
11276*67e74705SXin Li                                  const InputInfoList &Inputs,
11277*67e74705SXin Li                                  const ArgList &Args,
11278*67e74705SXin Li                                  const char *LinkingOutput) const {
11279*67e74705SXin Li   const auto &TC =
11280*67e74705SXin Li       static_cast<const toolchains::CudaToolChain &>(getToolChain());
11281*67e74705SXin Li   assert(TC.getTriple().isNVPTX() && "Wrong platform");
11282*67e74705SXin Li 
11283*67e74705SXin Li   ArgStringList CmdArgs;
11284*67e74705SXin Li   CmdArgs.push_back("--cuda");
11285*67e74705SXin Li   CmdArgs.push_back(TC.getTriple().isArch64Bit() ? "-64" : "-32");
11286*67e74705SXin Li   CmdArgs.push_back(Args.MakeArgString("--create"));
11287*67e74705SXin Li   CmdArgs.push_back(Args.MakeArgString(Output.getFilename()));
11288*67e74705SXin Li 
11289*67e74705SXin Li   for (const auto& II : Inputs) {
11290*67e74705SXin Li     auto* A = cast<const CudaDeviceAction>(II.getAction());
11291*67e74705SXin Li     // We need to pass an Arch of the form "sm_XX" for cubin files and
11292*67e74705SXin Li     // "compute_XX" for ptx.
11293*67e74705SXin Li     const char *Arch =
11294*67e74705SXin Li         (II.getType() == types::TY_PP_Asm)
11295*67e74705SXin Li             ? CudaVirtualArchToString(VirtualArchForCudaArch(A->getGpuArch()))
11296*67e74705SXin Li             : CudaArchToString(A->getGpuArch());
11297*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(llvm::Twine("--image=profile=") +
11298*67e74705SXin Li                                          Arch + ",file=" + II.getFilename()));
11299*67e74705SXin Li   }
11300*67e74705SXin Li 
11301*67e74705SXin Li   for (const auto& A : Args.getAllArgValues(options::OPT_Xcuda_fatbinary))
11302*67e74705SXin Li     CmdArgs.push_back(Args.MakeArgString(A));
11303*67e74705SXin Li 
11304*67e74705SXin Li   const char *Exec = Args.MakeArgString(TC.GetProgramPath("fatbinary"));
11305*67e74705SXin Li   C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
11306*67e74705SXin Li }
11307