1f4a2713aSLionel Sambuc //===--- Tools.cpp - Tools Implementations --------------------------------===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc // The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc
10f4a2713aSLionel Sambuc #include "Tools.h"
11f4a2713aSLionel Sambuc #include "InputInfo.h"
12f4a2713aSLionel Sambuc #include "ToolChains.h"
13*0a6a1f1dSLionel Sambuc #include "clang/Basic/LangOptions.h"
14f4a2713aSLionel Sambuc #include "clang/Basic/ObjCRuntime.h"
15f4a2713aSLionel Sambuc #include "clang/Basic/Version.h"
16*0a6a1f1dSLionel Sambuc #include "clang/Config/config.h"
17f4a2713aSLionel Sambuc #include "clang/Driver/Action.h"
18f4a2713aSLionel Sambuc #include "clang/Driver/Compilation.h"
19f4a2713aSLionel Sambuc #include "clang/Driver/Driver.h"
20f4a2713aSLionel Sambuc #include "clang/Driver/DriverDiagnostic.h"
21f4a2713aSLionel Sambuc #include "clang/Driver/Job.h"
22f4a2713aSLionel Sambuc #include "clang/Driver/Options.h"
23f4a2713aSLionel Sambuc #include "clang/Driver/SanitizerArgs.h"
24f4a2713aSLionel Sambuc #include "clang/Driver/ToolChain.h"
25f4a2713aSLionel Sambuc #include "clang/Driver/Util.h"
26f4a2713aSLionel Sambuc #include "llvm/ADT/SmallString.h"
27f4a2713aSLionel Sambuc #include "llvm/ADT/StringExtras.h"
28f4a2713aSLionel Sambuc #include "llvm/ADT/StringSwitch.h"
29f4a2713aSLionel Sambuc #include "llvm/ADT/Twine.h"
30f4a2713aSLionel Sambuc #include "llvm/Option/Arg.h"
31f4a2713aSLionel Sambuc #include "llvm/Option/ArgList.h"
32f4a2713aSLionel Sambuc #include "llvm/Option/Option.h"
33*0a6a1f1dSLionel Sambuc #include "llvm/Support/Compression.h"
34f4a2713aSLionel Sambuc #include "llvm/Support/ErrorHandling.h"
35f4a2713aSLionel Sambuc #include "llvm/Support/FileSystem.h"
36f4a2713aSLionel Sambuc #include "llvm/Support/Format.h"
37f4a2713aSLionel Sambuc #include "llvm/Support/Host.h"
38f4a2713aSLionel Sambuc #include "llvm/Support/Path.h"
39f4a2713aSLionel Sambuc #include "llvm/Support/Process.h"
40*0a6a1f1dSLionel Sambuc #include "llvm/Support/Program.h"
41f4a2713aSLionel Sambuc #include "llvm/Support/raw_ostream.h"
42f4a2713aSLionel Sambuc
43f4a2713aSLionel Sambuc using namespace clang::driver;
44f4a2713aSLionel Sambuc using namespace clang::driver::tools;
45f4a2713aSLionel Sambuc using namespace clang;
46f4a2713aSLionel Sambuc using namespace llvm::opt;
47f4a2713aSLionel Sambuc
addAssemblerKPIC(const ArgList & Args,ArgStringList & CmdArgs)48*0a6a1f1dSLionel Sambuc static void addAssemblerKPIC(const ArgList &Args, ArgStringList &CmdArgs) {
49*0a6a1f1dSLionel Sambuc Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC,
50*0a6a1f1dSLionel Sambuc options::OPT_fpic, options::OPT_fno_pic,
51*0a6a1f1dSLionel Sambuc options::OPT_fPIE, options::OPT_fno_PIE,
52*0a6a1f1dSLionel Sambuc options::OPT_fpie, options::OPT_fno_pie);
53*0a6a1f1dSLionel Sambuc if (!LastPICArg)
54*0a6a1f1dSLionel Sambuc return;
55*0a6a1f1dSLionel Sambuc if (LastPICArg->getOption().matches(options::OPT_fPIC) ||
56*0a6a1f1dSLionel Sambuc LastPICArg->getOption().matches(options::OPT_fpic) ||
57*0a6a1f1dSLionel Sambuc LastPICArg->getOption().matches(options::OPT_fPIE) ||
58*0a6a1f1dSLionel Sambuc LastPICArg->getOption().matches(options::OPT_fpie)) {
59*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-KPIC");
60*0a6a1f1dSLionel Sambuc }
61*0a6a1f1dSLionel Sambuc }
62*0a6a1f1dSLionel Sambuc
63f4a2713aSLionel Sambuc /// CheckPreprocessingOptions - Perform some validation of preprocessing
64f4a2713aSLionel Sambuc /// arguments that is shared with gcc.
CheckPreprocessingOptions(const Driver & D,const ArgList & Args)65f4a2713aSLionel Sambuc static void CheckPreprocessingOptions(const Driver &D, const ArgList &Args) {
66*0a6a1f1dSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_C, options::OPT_CC)) {
67*0a6a1f1dSLionel Sambuc if (!Args.hasArg(options::OPT_E) && !Args.hasArg(options::OPT__SLASH_P) &&
68*0a6a1f1dSLionel Sambuc !Args.hasArg(options::OPT__SLASH_EP) && !D.CCCIsCPP()) {
69f4a2713aSLionel Sambuc D.Diag(diag::err_drv_argument_only_allowed_with)
70*0a6a1f1dSLionel Sambuc << A->getBaseArg().getAsString(Args)
71*0a6a1f1dSLionel Sambuc << (D.IsCLMode() ? "/E, /P or /EP" : "-E");
72*0a6a1f1dSLionel Sambuc }
73*0a6a1f1dSLionel Sambuc }
74f4a2713aSLionel Sambuc }
75f4a2713aSLionel Sambuc
76f4a2713aSLionel Sambuc /// CheckCodeGenerationOptions - Perform some validation of code generation
77f4a2713aSLionel Sambuc /// arguments that is shared with gcc.
CheckCodeGenerationOptions(const Driver & D,const ArgList & Args)78f4a2713aSLionel Sambuc static void CheckCodeGenerationOptions(const Driver &D, const ArgList &Args) {
79f4a2713aSLionel Sambuc // In gcc, only ARM checks this, but it seems reasonable to check universally.
80f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_static))
81f4a2713aSLionel Sambuc if (const Arg *A = Args.getLastArg(options::OPT_dynamic,
82f4a2713aSLionel Sambuc options::OPT_mdynamic_no_pic))
83f4a2713aSLionel Sambuc D.Diag(diag::err_drv_argument_not_allowed_with)
84f4a2713aSLionel Sambuc << A->getAsString(Args) << "-static";
85f4a2713aSLionel Sambuc }
86f4a2713aSLionel Sambuc
87*0a6a1f1dSLionel Sambuc // Add backslashes to escape spaces and other backslashes.
88*0a6a1f1dSLionel Sambuc // This is used for the space-separated argument list specified with
89*0a6a1f1dSLionel Sambuc // the -dwarf-debug-flags option.
EscapeSpacesAndBackslashes(const char * Arg,SmallVectorImpl<char> & Res)90*0a6a1f1dSLionel Sambuc static void EscapeSpacesAndBackslashes(const char *Arg,
91*0a6a1f1dSLionel Sambuc SmallVectorImpl<char> &Res) {
92*0a6a1f1dSLionel Sambuc for ( ; *Arg; ++Arg) {
93*0a6a1f1dSLionel Sambuc switch (*Arg) {
94*0a6a1f1dSLionel Sambuc default: break;
95*0a6a1f1dSLionel Sambuc case ' ':
96*0a6a1f1dSLionel Sambuc case '\\':
97*0a6a1f1dSLionel Sambuc Res.push_back('\\');
98*0a6a1f1dSLionel Sambuc break;
99*0a6a1f1dSLionel Sambuc }
100*0a6a1f1dSLionel Sambuc Res.push_back(*Arg);
101*0a6a1f1dSLionel Sambuc }
102*0a6a1f1dSLionel Sambuc }
103*0a6a1f1dSLionel Sambuc
104f4a2713aSLionel Sambuc // Quote target names for inclusion in GNU Make dependency files.
105f4a2713aSLionel Sambuc // Only the characters '$', '#', ' ', '\t' are quoted.
QuoteTarget(StringRef Target,SmallVectorImpl<char> & Res)106f4a2713aSLionel Sambuc static void QuoteTarget(StringRef Target,
107f4a2713aSLionel Sambuc SmallVectorImpl<char> &Res) {
108f4a2713aSLionel Sambuc for (unsigned i = 0, e = Target.size(); i != e; ++i) {
109f4a2713aSLionel Sambuc switch (Target[i]) {
110f4a2713aSLionel Sambuc case ' ':
111f4a2713aSLionel Sambuc case '\t':
112f4a2713aSLionel Sambuc // Escape the preceding backslashes
113f4a2713aSLionel Sambuc for (int j = i - 1; j >= 0 && Target[j] == '\\'; --j)
114f4a2713aSLionel Sambuc Res.push_back('\\');
115f4a2713aSLionel Sambuc
116f4a2713aSLionel Sambuc // Escape the space/tab
117f4a2713aSLionel Sambuc Res.push_back('\\');
118f4a2713aSLionel Sambuc break;
119f4a2713aSLionel Sambuc case '$':
120f4a2713aSLionel Sambuc Res.push_back('$');
121f4a2713aSLionel Sambuc break;
122f4a2713aSLionel Sambuc case '#':
123f4a2713aSLionel Sambuc Res.push_back('\\');
124f4a2713aSLionel Sambuc break;
125f4a2713aSLionel Sambuc default:
126f4a2713aSLionel Sambuc break;
127f4a2713aSLionel Sambuc }
128f4a2713aSLionel Sambuc
129f4a2713aSLionel Sambuc Res.push_back(Target[i]);
130f4a2713aSLionel Sambuc }
131f4a2713aSLionel Sambuc }
132f4a2713aSLionel Sambuc
addDirectoryList(const ArgList & Args,ArgStringList & CmdArgs,const char * ArgName,const char * EnvVar)133f4a2713aSLionel Sambuc static void addDirectoryList(const ArgList &Args,
134f4a2713aSLionel Sambuc ArgStringList &CmdArgs,
135f4a2713aSLionel Sambuc const char *ArgName,
136f4a2713aSLionel Sambuc const char *EnvVar) {
137f4a2713aSLionel Sambuc const char *DirList = ::getenv(EnvVar);
138f4a2713aSLionel Sambuc bool CombinedArg = false;
139f4a2713aSLionel Sambuc
140f4a2713aSLionel Sambuc if (!DirList)
141f4a2713aSLionel Sambuc return; // Nothing to do.
142f4a2713aSLionel Sambuc
143f4a2713aSLionel Sambuc StringRef Name(ArgName);
144f4a2713aSLionel Sambuc if (Name.equals("-I") || Name.equals("-L"))
145f4a2713aSLionel Sambuc CombinedArg = true;
146f4a2713aSLionel Sambuc
147f4a2713aSLionel Sambuc StringRef Dirs(DirList);
148f4a2713aSLionel Sambuc if (Dirs.empty()) // Empty string should not add '.'.
149f4a2713aSLionel Sambuc return;
150f4a2713aSLionel Sambuc
151f4a2713aSLionel Sambuc StringRef::size_type Delim;
152f4a2713aSLionel Sambuc while ((Delim = Dirs.find(llvm::sys::EnvPathSeparator)) != StringRef::npos) {
153f4a2713aSLionel Sambuc if (Delim == 0) { // Leading colon.
154f4a2713aSLionel Sambuc if (CombinedArg) {
155f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(std::string(ArgName) + "."));
156f4a2713aSLionel Sambuc } else {
157f4a2713aSLionel Sambuc CmdArgs.push_back(ArgName);
158f4a2713aSLionel Sambuc CmdArgs.push_back(".");
159f4a2713aSLionel Sambuc }
160f4a2713aSLionel Sambuc } else {
161f4a2713aSLionel Sambuc if (CombinedArg) {
162f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(std::string(ArgName) + Dirs.substr(0, Delim)));
163f4a2713aSLionel Sambuc } else {
164f4a2713aSLionel Sambuc CmdArgs.push_back(ArgName);
165f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(Dirs.substr(0, Delim)));
166f4a2713aSLionel Sambuc }
167f4a2713aSLionel Sambuc }
168f4a2713aSLionel Sambuc Dirs = Dirs.substr(Delim + 1);
169f4a2713aSLionel Sambuc }
170f4a2713aSLionel Sambuc
171f4a2713aSLionel Sambuc if (Dirs.empty()) { // Trailing colon.
172f4a2713aSLionel Sambuc if (CombinedArg) {
173f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(std::string(ArgName) + "."));
174f4a2713aSLionel Sambuc } else {
175f4a2713aSLionel Sambuc CmdArgs.push_back(ArgName);
176f4a2713aSLionel Sambuc CmdArgs.push_back(".");
177f4a2713aSLionel Sambuc }
178f4a2713aSLionel Sambuc } else { // Add the last path.
179f4a2713aSLionel Sambuc if (CombinedArg) {
180f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(std::string(ArgName) + Dirs));
181f4a2713aSLionel Sambuc } else {
182f4a2713aSLionel Sambuc CmdArgs.push_back(ArgName);
183f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(Dirs));
184f4a2713aSLionel Sambuc }
185f4a2713aSLionel Sambuc }
186f4a2713aSLionel Sambuc }
187f4a2713aSLionel Sambuc
AddLinkerInputs(const ToolChain & TC,const InputInfoList & Inputs,const ArgList & Args,ArgStringList & CmdArgs)188f4a2713aSLionel Sambuc static void AddLinkerInputs(const ToolChain &TC,
189f4a2713aSLionel Sambuc const InputInfoList &Inputs, const ArgList &Args,
190f4a2713aSLionel Sambuc ArgStringList &CmdArgs) {
191f4a2713aSLionel Sambuc const Driver &D = TC.getDriver();
192f4a2713aSLionel Sambuc
193f4a2713aSLionel Sambuc // Add extra linker input arguments which are not treated as inputs
194f4a2713aSLionel Sambuc // (constructed via -Xarch_).
195f4a2713aSLionel Sambuc Args.AddAllArgValues(CmdArgs, options::OPT_Zlinker_input);
196f4a2713aSLionel Sambuc
197*0a6a1f1dSLionel Sambuc for (const auto &II : Inputs) {
198f4a2713aSLionel Sambuc if (!TC.HasNativeLLVMSupport()) {
199f4a2713aSLionel Sambuc // Don't try to pass LLVM inputs unless we have native support.
200f4a2713aSLionel Sambuc if (II.getType() == types::TY_LLVM_IR ||
201f4a2713aSLionel Sambuc II.getType() == types::TY_LTO_IR ||
202f4a2713aSLionel Sambuc II.getType() == types::TY_LLVM_BC ||
203f4a2713aSLionel Sambuc II.getType() == types::TY_LTO_BC)
204f4a2713aSLionel Sambuc D.Diag(diag::err_drv_no_linker_llvm_support)
205f4a2713aSLionel Sambuc << TC.getTripleString();
206f4a2713aSLionel Sambuc }
207f4a2713aSLionel Sambuc
208f4a2713aSLionel Sambuc // Add filenames immediately.
209f4a2713aSLionel Sambuc if (II.isFilename()) {
210f4a2713aSLionel Sambuc CmdArgs.push_back(II.getFilename());
211f4a2713aSLionel Sambuc continue;
212f4a2713aSLionel Sambuc }
213f4a2713aSLionel Sambuc
214f4a2713aSLionel Sambuc // Otherwise, this is a linker input argument.
215f4a2713aSLionel Sambuc const Arg &A = II.getInputArg();
216f4a2713aSLionel Sambuc
217f4a2713aSLionel Sambuc // Handle reserved library options.
218*0a6a1f1dSLionel Sambuc if (A.getOption().matches(options::OPT_Z_reserved_lib_stdcxx))
219f4a2713aSLionel Sambuc TC.AddCXXStdlibLibArgs(Args, CmdArgs);
220*0a6a1f1dSLionel Sambuc else if (A.getOption().matches(options::OPT_Z_reserved_lib_cckext))
221f4a2713aSLionel Sambuc TC.AddCCKextLibArgs(Args, CmdArgs);
222*0a6a1f1dSLionel Sambuc else if (A.getOption().matches(options::OPT_z)) {
223*0a6a1f1dSLionel Sambuc // Pass -z prefix for gcc linker compatibility.
224*0a6a1f1dSLionel Sambuc A.claim();
225*0a6a1f1dSLionel Sambuc A.render(Args, CmdArgs);
226*0a6a1f1dSLionel Sambuc } else {
227f4a2713aSLionel Sambuc A.renderAsInput(Args, CmdArgs);
228f4a2713aSLionel Sambuc }
229*0a6a1f1dSLionel Sambuc }
230f4a2713aSLionel Sambuc
231f4a2713aSLionel Sambuc // LIBRARY_PATH - included following the user specified library paths.
232*0a6a1f1dSLionel Sambuc // and only supported on native toolchains.
233*0a6a1f1dSLionel Sambuc if (!TC.isCrossCompiling())
234f4a2713aSLionel Sambuc addDirectoryList(Args, CmdArgs, "-L", "LIBRARY_PATH");
235f4a2713aSLionel Sambuc }
236f4a2713aSLionel Sambuc
237f4a2713aSLionel Sambuc /// \brief Determine whether Objective-C automated reference counting is
238f4a2713aSLionel Sambuc /// enabled.
isObjCAutoRefCount(const ArgList & Args)239f4a2713aSLionel Sambuc static bool isObjCAutoRefCount(const ArgList &Args) {
240f4a2713aSLionel Sambuc return Args.hasFlag(options::OPT_fobjc_arc, options::OPT_fno_objc_arc, false);
241f4a2713aSLionel Sambuc }
242f4a2713aSLionel Sambuc
243f4a2713aSLionel Sambuc /// \brief Determine whether we are linking the ObjC runtime.
isObjCRuntimeLinked(const ArgList & Args)244f4a2713aSLionel Sambuc static bool isObjCRuntimeLinked(const ArgList &Args) {
245f4a2713aSLionel Sambuc if (isObjCAutoRefCount(Args)) {
246f4a2713aSLionel Sambuc Args.ClaimAllArgs(options::OPT_fobjc_link_runtime);
247f4a2713aSLionel Sambuc return true;
248f4a2713aSLionel Sambuc }
249f4a2713aSLionel Sambuc return Args.hasArg(options::OPT_fobjc_link_runtime);
250f4a2713aSLionel Sambuc }
251f4a2713aSLionel Sambuc
forwardToGCC(const Option & O)252f4a2713aSLionel Sambuc static bool forwardToGCC(const Option &O) {
253f4a2713aSLionel Sambuc // Don't forward inputs from the original command line. They are added from
254f4a2713aSLionel Sambuc // InputInfoList.
255f4a2713aSLionel Sambuc return O.getKind() != Option::InputClass &&
256f4a2713aSLionel Sambuc !O.hasFlag(options::DriverOption) &&
257f4a2713aSLionel Sambuc !O.hasFlag(options::LinkerInput);
258f4a2713aSLionel Sambuc }
259f4a2713aSLionel Sambuc
AddPreprocessingOptions(Compilation & C,const JobAction & JA,const Driver & D,const ArgList & Args,ArgStringList & CmdArgs,const InputInfo & Output,const InputInfoList & Inputs) const260f4a2713aSLionel Sambuc void Clang::AddPreprocessingOptions(Compilation &C,
261f4a2713aSLionel Sambuc const JobAction &JA,
262f4a2713aSLionel Sambuc const Driver &D,
263f4a2713aSLionel Sambuc const ArgList &Args,
264f4a2713aSLionel Sambuc ArgStringList &CmdArgs,
265f4a2713aSLionel Sambuc const InputInfo &Output,
266f4a2713aSLionel Sambuc const InputInfoList &Inputs) const {
267f4a2713aSLionel Sambuc Arg *A;
268f4a2713aSLionel Sambuc
269f4a2713aSLionel Sambuc CheckPreprocessingOptions(D, Args);
270f4a2713aSLionel Sambuc
271f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_C);
272f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_CC);
273f4a2713aSLionel Sambuc
274f4a2713aSLionel Sambuc // Handle dependency file generation.
275f4a2713aSLionel Sambuc if ((A = Args.getLastArg(options::OPT_M, options::OPT_MM)) ||
276f4a2713aSLionel Sambuc (A = Args.getLastArg(options::OPT_MD)) ||
277f4a2713aSLionel Sambuc (A = Args.getLastArg(options::OPT_MMD))) {
278f4a2713aSLionel Sambuc // Determine the output location.
279f4a2713aSLionel Sambuc const char *DepFile;
280f4a2713aSLionel Sambuc if (Arg *MF = Args.getLastArg(options::OPT_MF)) {
281f4a2713aSLionel Sambuc DepFile = MF->getValue();
282f4a2713aSLionel Sambuc C.addFailureResultFile(DepFile, &JA);
283f4a2713aSLionel Sambuc } else if (Output.getType() == types::TY_Dependencies) {
284f4a2713aSLionel Sambuc DepFile = Output.getFilename();
285f4a2713aSLionel Sambuc } else if (A->getOption().matches(options::OPT_M) ||
286f4a2713aSLionel Sambuc A->getOption().matches(options::OPT_MM)) {
287f4a2713aSLionel Sambuc DepFile = "-";
288f4a2713aSLionel Sambuc } else {
289f4a2713aSLionel Sambuc DepFile = getDependencyFileName(Args, Inputs);
290f4a2713aSLionel Sambuc C.addFailureResultFile(DepFile, &JA);
291f4a2713aSLionel Sambuc }
292f4a2713aSLionel Sambuc CmdArgs.push_back("-dependency-file");
293f4a2713aSLionel Sambuc CmdArgs.push_back(DepFile);
294f4a2713aSLionel Sambuc
295f4a2713aSLionel Sambuc // Add a default target if one wasn't specified.
296f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_MT) && !Args.hasArg(options::OPT_MQ)) {
297f4a2713aSLionel Sambuc const char *DepTarget;
298f4a2713aSLionel Sambuc
299f4a2713aSLionel Sambuc // If user provided -o, that is the dependency target, except
300f4a2713aSLionel Sambuc // when we are only generating a dependency file.
301f4a2713aSLionel Sambuc Arg *OutputOpt = Args.getLastArg(options::OPT_o);
302f4a2713aSLionel Sambuc if (OutputOpt && Output.getType() != types::TY_Dependencies) {
303f4a2713aSLionel Sambuc DepTarget = OutputOpt->getValue();
304f4a2713aSLionel Sambuc } else {
305f4a2713aSLionel Sambuc // Otherwise derive from the base input.
306f4a2713aSLionel Sambuc //
307f4a2713aSLionel Sambuc // FIXME: This should use the computed output file location.
308f4a2713aSLionel Sambuc SmallString<128> P(Inputs[0].getBaseInput());
309f4a2713aSLionel Sambuc llvm::sys::path::replace_extension(P, "o");
310f4a2713aSLionel Sambuc DepTarget = Args.MakeArgString(llvm::sys::path::filename(P));
311f4a2713aSLionel Sambuc }
312f4a2713aSLionel Sambuc
313f4a2713aSLionel Sambuc CmdArgs.push_back("-MT");
314f4a2713aSLionel Sambuc SmallString<128> Quoted;
315f4a2713aSLionel Sambuc QuoteTarget(DepTarget, Quoted);
316f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(Quoted));
317f4a2713aSLionel Sambuc }
318f4a2713aSLionel Sambuc
319f4a2713aSLionel Sambuc if (A->getOption().matches(options::OPT_M) ||
320f4a2713aSLionel Sambuc A->getOption().matches(options::OPT_MD))
321f4a2713aSLionel Sambuc CmdArgs.push_back("-sys-header-deps");
322*0a6a1f1dSLionel Sambuc
323*0a6a1f1dSLionel Sambuc if (isa<PrecompileJobAction>(JA))
324*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-module-file-deps");
325f4a2713aSLionel Sambuc }
326f4a2713aSLionel Sambuc
327f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_MG)) {
328f4a2713aSLionel Sambuc if (!A || A->getOption().matches(options::OPT_MD) ||
329f4a2713aSLionel Sambuc A->getOption().matches(options::OPT_MMD))
330f4a2713aSLionel Sambuc D.Diag(diag::err_drv_mg_requires_m_or_mm);
331f4a2713aSLionel Sambuc CmdArgs.push_back("-MG");
332f4a2713aSLionel Sambuc }
333f4a2713aSLionel Sambuc
334f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_MP);
335f4a2713aSLionel Sambuc
336f4a2713aSLionel Sambuc // Convert all -MQ <target> args to -MT <quoted target>
337f4a2713aSLionel Sambuc for (arg_iterator it = Args.filtered_begin(options::OPT_MT,
338f4a2713aSLionel Sambuc options::OPT_MQ),
339f4a2713aSLionel Sambuc ie = Args.filtered_end(); it != ie; ++it) {
340f4a2713aSLionel Sambuc const Arg *A = *it;
341f4a2713aSLionel Sambuc A->claim();
342f4a2713aSLionel Sambuc
343f4a2713aSLionel Sambuc if (A->getOption().matches(options::OPT_MQ)) {
344f4a2713aSLionel Sambuc CmdArgs.push_back("-MT");
345f4a2713aSLionel Sambuc SmallString<128> Quoted;
346f4a2713aSLionel Sambuc QuoteTarget(A->getValue(), Quoted);
347f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(Quoted));
348f4a2713aSLionel Sambuc
349f4a2713aSLionel Sambuc // -MT flag - no change
350f4a2713aSLionel Sambuc } else {
351f4a2713aSLionel Sambuc A->render(Args, CmdArgs);
352f4a2713aSLionel Sambuc }
353f4a2713aSLionel Sambuc }
354f4a2713aSLionel Sambuc
355f4a2713aSLionel Sambuc // Add -i* options, and automatically translate to
356f4a2713aSLionel Sambuc // -include-pch/-include-pth for transparent PCH support. It's
357f4a2713aSLionel Sambuc // wonky, but we include looking for .gch so we can support seamless
358f4a2713aSLionel Sambuc // replacement into a build system already set up to be generating
359f4a2713aSLionel Sambuc // .gch files.
360f4a2713aSLionel Sambuc bool RenderedImplicitInclude = false;
361f4a2713aSLionel Sambuc for (arg_iterator it = Args.filtered_begin(options::OPT_clang_i_Group),
362f4a2713aSLionel Sambuc ie = Args.filtered_end(); it != ie; ++it) {
363f4a2713aSLionel Sambuc const Arg *A = it;
364f4a2713aSLionel Sambuc
365f4a2713aSLionel Sambuc if (A->getOption().matches(options::OPT_include)) {
366f4a2713aSLionel Sambuc bool IsFirstImplicitInclude = !RenderedImplicitInclude;
367f4a2713aSLionel Sambuc RenderedImplicitInclude = true;
368f4a2713aSLionel Sambuc
369f4a2713aSLionel Sambuc // Use PCH if the user requested it.
370f4a2713aSLionel Sambuc bool UsePCH = D.CCCUsePCH;
371f4a2713aSLionel Sambuc
372f4a2713aSLionel Sambuc bool FoundPTH = false;
373f4a2713aSLionel Sambuc bool FoundPCH = false;
374f4a2713aSLionel Sambuc SmallString<128> P(A->getValue());
375f4a2713aSLionel Sambuc // We want the files to have a name like foo.h.pch. Add a dummy extension
376f4a2713aSLionel Sambuc // so that replace_extension does the right thing.
377f4a2713aSLionel Sambuc P += ".dummy";
378f4a2713aSLionel Sambuc if (UsePCH) {
379f4a2713aSLionel Sambuc llvm::sys::path::replace_extension(P, "pch");
380f4a2713aSLionel Sambuc if (llvm::sys::fs::exists(P.str()))
381f4a2713aSLionel Sambuc FoundPCH = true;
382f4a2713aSLionel Sambuc }
383f4a2713aSLionel Sambuc
384f4a2713aSLionel Sambuc if (!FoundPCH) {
385f4a2713aSLionel Sambuc llvm::sys::path::replace_extension(P, "pth");
386f4a2713aSLionel Sambuc if (llvm::sys::fs::exists(P.str()))
387f4a2713aSLionel Sambuc FoundPTH = true;
388f4a2713aSLionel Sambuc }
389f4a2713aSLionel Sambuc
390f4a2713aSLionel Sambuc if (!FoundPCH && !FoundPTH) {
391f4a2713aSLionel Sambuc llvm::sys::path::replace_extension(P, "gch");
392f4a2713aSLionel Sambuc if (llvm::sys::fs::exists(P.str())) {
393f4a2713aSLionel Sambuc FoundPCH = UsePCH;
394f4a2713aSLionel Sambuc FoundPTH = !UsePCH;
395f4a2713aSLionel Sambuc }
396f4a2713aSLionel Sambuc }
397f4a2713aSLionel Sambuc
398f4a2713aSLionel Sambuc if (FoundPCH || FoundPTH) {
399f4a2713aSLionel Sambuc if (IsFirstImplicitInclude) {
400f4a2713aSLionel Sambuc A->claim();
401f4a2713aSLionel Sambuc if (UsePCH)
402f4a2713aSLionel Sambuc CmdArgs.push_back("-include-pch");
403f4a2713aSLionel Sambuc else
404f4a2713aSLionel Sambuc CmdArgs.push_back("-include-pth");
405f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(P.str()));
406f4a2713aSLionel Sambuc continue;
407f4a2713aSLionel Sambuc } else {
408f4a2713aSLionel Sambuc // Ignore the PCH if not first on command line and emit warning.
409f4a2713aSLionel Sambuc D.Diag(diag::warn_drv_pch_not_first_include)
410f4a2713aSLionel Sambuc << P.str() << A->getAsString(Args);
411f4a2713aSLionel Sambuc }
412f4a2713aSLionel Sambuc }
413f4a2713aSLionel Sambuc }
414f4a2713aSLionel Sambuc
415f4a2713aSLionel Sambuc // Not translated, render as usual.
416f4a2713aSLionel Sambuc A->claim();
417f4a2713aSLionel Sambuc A->render(Args, CmdArgs);
418f4a2713aSLionel Sambuc }
419f4a2713aSLionel Sambuc
420f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_D, options::OPT_U);
421f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_I_Group, options::OPT_F,
422f4a2713aSLionel Sambuc options::OPT_index_header_map);
423f4a2713aSLionel Sambuc
424f4a2713aSLionel Sambuc // Add -Wp, and -Xassembler if using the preprocessor.
425f4a2713aSLionel Sambuc
426f4a2713aSLionel Sambuc // FIXME: There is a very unfortunate problem here, some troubled
427f4a2713aSLionel Sambuc // souls abuse -Wp, to pass preprocessor options in gcc syntax. To
428f4a2713aSLionel Sambuc // really support that we would have to parse and then translate
429f4a2713aSLionel Sambuc // those options. :(
430f4a2713aSLionel Sambuc Args.AddAllArgValues(CmdArgs, options::OPT_Wp_COMMA,
431f4a2713aSLionel Sambuc options::OPT_Xpreprocessor);
432f4a2713aSLionel Sambuc
433f4a2713aSLionel Sambuc // -I- is a deprecated GCC feature, reject it.
434f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_I_))
435f4a2713aSLionel Sambuc D.Diag(diag::err_drv_I_dash_not_supported) << A->getAsString(Args);
436f4a2713aSLionel Sambuc
437f4a2713aSLionel Sambuc // If we have a --sysroot, and don't have an explicit -isysroot flag, add an
438f4a2713aSLionel Sambuc // -isysroot to the CC1 invocation.
439f4a2713aSLionel Sambuc StringRef sysroot = C.getSysRoot();
440f4a2713aSLionel Sambuc if (sysroot != "") {
441f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_isysroot)) {
442f4a2713aSLionel Sambuc CmdArgs.push_back("-isysroot");
443f4a2713aSLionel Sambuc CmdArgs.push_back(C.getArgs().MakeArgString(sysroot));
444f4a2713aSLionel Sambuc }
445f4a2713aSLionel Sambuc }
446f4a2713aSLionel Sambuc
447f4a2713aSLionel Sambuc // Parse additional include paths from environment variables.
448f4a2713aSLionel Sambuc // FIXME: We should probably sink the logic for handling these from the
449f4a2713aSLionel Sambuc // frontend into the driver. It will allow deleting 4 otherwise unused flags.
450f4a2713aSLionel Sambuc // CPATH - included following the user specified includes (but prior to
451f4a2713aSLionel Sambuc // builtin and standard includes).
452f4a2713aSLionel Sambuc addDirectoryList(Args, CmdArgs, "-I", "CPATH");
453f4a2713aSLionel Sambuc // C_INCLUDE_PATH - system includes enabled when compiling C.
454f4a2713aSLionel Sambuc addDirectoryList(Args, CmdArgs, "-c-isystem", "C_INCLUDE_PATH");
455f4a2713aSLionel Sambuc // CPLUS_INCLUDE_PATH - system includes enabled when compiling C++.
456f4a2713aSLionel Sambuc addDirectoryList(Args, CmdArgs, "-cxx-isystem", "CPLUS_INCLUDE_PATH");
457f4a2713aSLionel Sambuc // OBJC_INCLUDE_PATH - system includes enabled when compiling ObjC.
458f4a2713aSLionel Sambuc addDirectoryList(Args, CmdArgs, "-objc-isystem", "OBJC_INCLUDE_PATH");
459f4a2713aSLionel Sambuc // OBJCPLUS_INCLUDE_PATH - system includes enabled when compiling ObjC++.
460f4a2713aSLionel Sambuc addDirectoryList(Args, CmdArgs, "-objcxx-isystem", "OBJCPLUS_INCLUDE_PATH");
461f4a2713aSLionel Sambuc
462f4a2713aSLionel Sambuc // Add C++ include arguments, if needed.
463f4a2713aSLionel Sambuc if (types::isCXX(Inputs[0].getType()))
464f4a2713aSLionel Sambuc getToolChain().AddClangCXXStdlibIncludeArgs(Args, CmdArgs);
465f4a2713aSLionel Sambuc
466f4a2713aSLionel Sambuc // Add system include arguments.
467f4a2713aSLionel Sambuc getToolChain().AddClangSystemIncludeArgs(Args, CmdArgs);
468f4a2713aSLionel Sambuc }
469f4a2713aSLionel Sambuc
470f4a2713aSLionel Sambuc // FIXME: Move to target hook.
isSignedCharDefault(const llvm::Triple & Triple)471f4a2713aSLionel Sambuc static bool isSignedCharDefault(const llvm::Triple &Triple) {
472f4a2713aSLionel Sambuc switch (Triple.getArch()) {
473f4a2713aSLionel Sambuc default:
474f4a2713aSLionel Sambuc return true;
475f4a2713aSLionel Sambuc
476f4a2713aSLionel Sambuc case llvm::Triple::aarch64:
477*0a6a1f1dSLionel Sambuc case llvm::Triple::aarch64_be:
478f4a2713aSLionel Sambuc case llvm::Triple::arm:
479*0a6a1f1dSLionel Sambuc case llvm::Triple::armeb:
480*0a6a1f1dSLionel Sambuc case llvm::Triple::thumb:
481*0a6a1f1dSLionel Sambuc case llvm::Triple::thumbeb:
482*0a6a1f1dSLionel Sambuc if (Triple.isOSDarwin() || Triple.isOSWindows())
483*0a6a1f1dSLionel Sambuc return true;
484*0a6a1f1dSLionel Sambuc return false;
485*0a6a1f1dSLionel Sambuc
486f4a2713aSLionel Sambuc case llvm::Triple::ppc:
487f4a2713aSLionel Sambuc case llvm::Triple::ppc64:
488f4a2713aSLionel Sambuc if (Triple.isOSDarwin())
489f4a2713aSLionel Sambuc return true;
490f4a2713aSLionel Sambuc return false;
491f4a2713aSLionel Sambuc
492f4a2713aSLionel Sambuc case llvm::Triple::ppc64le:
493f4a2713aSLionel Sambuc case llvm::Triple::systemz:
494f4a2713aSLionel Sambuc case llvm::Triple::xcore:
495f4a2713aSLionel Sambuc return false;
496f4a2713aSLionel Sambuc }
497f4a2713aSLionel Sambuc }
498f4a2713aSLionel Sambuc
isNoCommonDefault(const llvm::Triple & Triple)499f4a2713aSLionel Sambuc static bool isNoCommonDefault(const llvm::Triple &Triple) {
500f4a2713aSLionel Sambuc switch (Triple.getArch()) {
501f4a2713aSLionel Sambuc default:
502f4a2713aSLionel Sambuc return false;
503f4a2713aSLionel Sambuc
504f4a2713aSLionel Sambuc case llvm::Triple::xcore:
505f4a2713aSLionel Sambuc return true;
506f4a2713aSLionel Sambuc }
507f4a2713aSLionel Sambuc }
508f4a2713aSLionel Sambuc
509f4a2713aSLionel Sambuc // Handle -mhwdiv=.
getARMHWDivFeatures(const Driver & D,const Arg * A,const ArgList & Args,std::vector<const char * > & Features)510f4a2713aSLionel Sambuc static void getARMHWDivFeatures(const Driver &D, const Arg *A,
511f4a2713aSLionel Sambuc const ArgList &Args,
512f4a2713aSLionel Sambuc std::vector<const char *> &Features) {
513f4a2713aSLionel Sambuc StringRef HWDiv = A->getValue();
514f4a2713aSLionel Sambuc if (HWDiv == "arm") {
515f4a2713aSLionel Sambuc Features.push_back("+hwdiv-arm");
516f4a2713aSLionel Sambuc Features.push_back("-hwdiv");
517f4a2713aSLionel Sambuc } else if (HWDiv == "thumb") {
518f4a2713aSLionel Sambuc Features.push_back("-hwdiv-arm");
519f4a2713aSLionel Sambuc Features.push_back("+hwdiv");
520f4a2713aSLionel Sambuc } else if (HWDiv == "arm,thumb" || HWDiv == "thumb,arm") {
521f4a2713aSLionel Sambuc Features.push_back("+hwdiv-arm");
522f4a2713aSLionel Sambuc Features.push_back("+hwdiv");
523f4a2713aSLionel Sambuc } else if (HWDiv == "none") {
524f4a2713aSLionel Sambuc Features.push_back("-hwdiv-arm");
525f4a2713aSLionel Sambuc Features.push_back("-hwdiv");
526f4a2713aSLionel Sambuc } else
527f4a2713aSLionel Sambuc D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
528f4a2713aSLionel Sambuc }
529f4a2713aSLionel Sambuc
530f4a2713aSLionel Sambuc // Handle -mfpu=.
531f4a2713aSLionel Sambuc //
532f4a2713aSLionel Sambuc // FIXME: Centralize feature selection, defaulting shouldn't be also in the
533f4a2713aSLionel Sambuc // frontend target.
getARMFPUFeatures(const Driver & D,const Arg * A,const ArgList & Args,std::vector<const char * > & Features)534f4a2713aSLionel Sambuc static void getARMFPUFeatures(const Driver &D, const Arg *A,
535f4a2713aSLionel Sambuc const ArgList &Args,
536f4a2713aSLionel Sambuc std::vector<const char *> &Features) {
537f4a2713aSLionel Sambuc StringRef FPU = A->getValue();
538f4a2713aSLionel Sambuc
539f4a2713aSLionel Sambuc // Set the target features based on the FPU.
540f4a2713aSLionel Sambuc if (FPU == "fpa" || FPU == "fpe2" || FPU == "fpe3" || FPU == "maverick") {
541f4a2713aSLionel Sambuc // Disable any default FPU support.
542f4a2713aSLionel Sambuc Features.push_back("-vfp2");
543f4a2713aSLionel Sambuc Features.push_back("-vfp3");
544f4a2713aSLionel Sambuc Features.push_back("-neon");
545*0a6a1f1dSLionel Sambuc } else if (FPU == "vfp") {
546*0a6a1f1dSLionel Sambuc Features.push_back("+vfp2");
547*0a6a1f1dSLionel Sambuc Features.push_back("-neon");
548f4a2713aSLionel Sambuc } else if (FPU == "vfp3-d16" || FPU == "vfpv3-d16") {
549f4a2713aSLionel Sambuc Features.push_back("+vfp3");
550f4a2713aSLionel Sambuc Features.push_back("+d16");
551f4a2713aSLionel Sambuc Features.push_back("-neon");
552f4a2713aSLionel Sambuc } else if (FPU == "vfp3" || FPU == "vfpv3") {
553f4a2713aSLionel Sambuc Features.push_back("+vfp3");
554f4a2713aSLionel Sambuc Features.push_back("-neon");
555*0a6a1f1dSLionel Sambuc } else if (FPU == "vfp4-d16" || FPU == "vfpv4-d16") {
556*0a6a1f1dSLionel Sambuc Features.push_back("+vfp4");
557*0a6a1f1dSLionel Sambuc Features.push_back("+d16");
558*0a6a1f1dSLionel Sambuc Features.push_back("-neon");
559*0a6a1f1dSLionel Sambuc } else if (FPU == "vfp4" || FPU == "vfpv4") {
560*0a6a1f1dSLionel Sambuc Features.push_back("+vfp4");
561*0a6a1f1dSLionel Sambuc Features.push_back("-neon");
562*0a6a1f1dSLionel Sambuc } else if (FPU == "fp4-sp-d16" || FPU == "fpv4-sp-d16") {
563*0a6a1f1dSLionel Sambuc Features.push_back("+vfp4");
564*0a6a1f1dSLionel Sambuc Features.push_back("+d16");
565*0a6a1f1dSLionel Sambuc Features.push_back("+fp-only-sp");
566*0a6a1f1dSLionel Sambuc Features.push_back("-neon");
567*0a6a1f1dSLionel Sambuc } else if (FPU == "fp5-sp-d16" || FPU == "fpv5-sp-d16") {
568*0a6a1f1dSLionel Sambuc Features.push_back("+fp-armv8");
569*0a6a1f1dSLionel Sambuc Features.push_back("+fp-only-sp");
570*0a6a1f1dSLionel Sambuc Features.push_back("+d16");
571*0a6a1f1dSLionel Sambuc Features.push_back("-neon");
572*0a6a1f1dSLionel Sambuc Features.push_back("-crypto");
573*0a6a1f1dSLionel Sambuc } else if (FPU == "fp5-dp-d16" || FPU == "fpv5-dp-d16" ||
574*0a6a1f1dSLionel Sambuc FPU == "fp5-d16" || FPU == "fpv5-d16") {
575*0a6a1f1dSLionel Sambuc Features.push_back("+fp-armv8");
576*0a6a1f1dSLionel Sambuc Features.push_back("+d16");
577*0a6a1f1dSLionel Sambuc Features.push_back("-neon");
578*0a6a1f1dSLionel Sambuc Features.push_back("-crypto");
579f4a2713aSLionel Sambuc } else if (FPU == "fp-armv8") {
580f4a2713aSLionel Sambuc Features.push_back("+fp-armv8");
581f4a2713aSLionel Sambuc Features.push_back("-neon");
582f4a2713aSLionel Sambuc Features.push_back("-crypto");
583f4a2713aSLionel Sambuc } else if (FPU == "neon-fp-armv8") {
584f4a2713aSLionel Sambuc Features.push_back("+fp-armv8");
585f4a2713aSLionel Sambuc Features.push_back("+neon");
586f4a2713aSLionel Sambuc Features.push_back("-crypto");
587f4a2713aSLionel Sambuc } else if (FPU == "crypto-neon-fp-armv8") {
588f4a2713aSLionel Sambuc Features.push_back("+fp-armv8");
589f4a2713aSLionel Sambuc Features.push_back("+neon");
590f4a2713aSLionel Sambuc Features.push_back("+crypto");
591f4a2713aSLionel Sambuc } else if (FPU == "neon") {
592f4a2713aSLionel Sambuc Features.push_back("+neon");
593*0a6a1f1dSLionel Sambuc } else if (FPU == "neon-vfpv3") {
594*0a6a1f1dSLionel Sambuc Features.push_back("+vfp3");
595*0a6a1f1dSLionel Sambuc Features.push_back("+neon");
596*0a6a1f1dSLionel Sambuc } else if (FPU == "neon-vfpv4") {
597*0a6a1f1dSLionel Sambuc Features.push_back("+neon");
598*0a6a1f1dSLionel Sambuc Features.push_back("+vfp4");
599f4a2713aSLionel Sambuc } else if (FPU == "none") {
600f4a2713aSLionel Sambuc Features.push_back("-vfp2");
601f4a2713aSLionel Sambuc Features.push_back("-vfp3");
602f4a2713aSLionel Sambuc Features.push_back("-vfp4");
603f4a2713aSLionel Sambuc Features.push_back("-fp-armv8");
604f4a2713aSLionel Sambuc Features.push_back("-crypto");
605f4a2713aSLionel Sambuc Features.push_back("-neon");
606f4a2713aSLionel Sambuc } else
607f4a2713aSLionel Sambuc D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
608f4a2713aSLionel Sambuc }
609f4a2713aSLionel Sambuc
610f4a2713aSLionel Sambuc // Select the float ABI as determined by -msoft-float, -mhard-float, and
611f4a2713aSLionel Sambuc // -mfloat-abi=.
getARMFloatABI(const Driver & D,const ArgList & Args,const llvm::Triple & Triple)612*0a6a1f1dSLionel Sambuc StringRef tools::arm::getARMFloatABI(const Driver &D, const ArgList &Args,
613f4a2713aSLionel Sambuc const llvm::Triple &Triple) {
614f4a2713aSLionel Sambuc StringRef FloatABI;
615f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_msoft_float,
616f4a2713aSLionel Sambuc options::OPT_mhard_float,
617f4a2713aSLionel Sambuc options::OPT_mfloat_abi_EQ)) {
618f4a2713aSLionel Sambuc if (A->getOption().matches(options::OPT_msoft_float))
619f4a2713aSLionel Sambuc FloatABI = "soft";
620f4a2713aSLionel Sambuc else if (A->getOption().matches(options::OPT_mhard_float))
621f4a2713aSLionel Sambuc FloatABI = "hard";
622f4a2713aSLionel Sambuc else {
623f4a2713aSLionel Sambuc FloatABI = A->getValue();
624f4a2713aSLionel Sambuc if (FloatABI != "soft" && FloatABI != "softfp" && FloatABI != "hard") {
625f4a2713aSLionel Sambuc D.Diag(diag::err_drv_invalid_mfloat_abi)
626f4a2713aSLionel Sambuc << A->getAsString(Args);
627f4a2713aSLionel Sambuc FloatABI = "soft";
628f4a2713aSLionel Sambuc }
629f4a2713aSLionel Sambuc }
630f4a2713aSLionel Sambuc }
631f4a2713aSLionel Sambuc
632f4a2713aSLionel Sambuc // If unspecified, choose the default based on the platform.
633f4a2713aSLionel Sambuc if (FloatABI.empty()) {
634f4a2713aSLionel Sambuc switch (Triple.getOS()) {
635f4a2713aSLionel Sambuc case llvm::Triple::Darwin:
636f4a2713aSLionel Sambuc case llvm::Triple::MacOSX:
637f4a2713aSLionel Sambuc case llvm::Triple::IOS: {
638f4a2713aSLionel Sambuc // Darwin defaults to "softfp" for v6 and v7.
639f4a2713aSLionel Sambuc //
640f4a2713aSLionel Sambuc // FIXME: Factor out an ARM class so we can cache the arch somewhere.
641f4a2713aSLionel Sambuc std::string ArchName =
642*0a6a1f1dSLionel Sambuc arm::getLLVMArchSuffixForARM(arm::getARMTargetCPU(Args, Triple));
643f4a2713aSLionel Sambuc if (StringRef(ArchName).startswith("v6") ||
644f4a2713aSLionel Sambuc StringRef(ArchName).startswith("v7"))
645f4a2713aSLionel Sambuc FloatABI = "softfp";
646f4a2713aSLionel Sambuc else
647f4a2713aSLionel Sambuc FloatABI = "soft";
648f4a2713aSLionel Sambuc break;
649f4a2713aSLionel Sambuc }
650f4a2713aSLionel Sambuc
651*0a6a1f1dSLionel Sambuc // FIXME: this is invalid for WindowsCE
652*0a6a1f1dSLionel Sambuc case llvm::Triple::Win32:
653*0a6a1f1dSLionel Sambuc FloatABI = "hard";
654*0a6a1f1dSLionel Sambuc break;
655*0a6a1f1dSLionel Sambuc
656f4a2713aSLionel Sambuc case llvm::Triple::FreeBSD:
657*0a6a1f1dSLionel Sambuc switch(Triple.getEnvironment()) {
658*0a6a1f1dSLionel Sambuc case llvm::Triple::GNUEABIHF:
659*0a6a1f1dSLionel Sambuc FloatABI = "hard";
660*0a6a1f1dSLionel Sambuc break;
661*0a6a1f1dSLionel Sambuc default:
662f4a2713aSLionel Sambuc // FreeBSD defaults to soft float
663f4a2713aSLionel Sambuc FloatABI = "soft";
664f4a2713aSLionel Sambuc break;
665*0a6a1f1dSLionel Sambuc }
666*0a6a1f1dSLionel Sambuc break;
667f4a2713aSLionel Sambuc
668f4a2713aSLionel Sambuc default:
669f4a2713aSLionel Sambuc switch(Triple.getEnvironment()) {
670f4a2713aSLionel Sambuc case llvm::Triple::GNUEABIHF:
671f4a2713aSLionel Sambuc FloatABI = "hard";
672f4a2713aSLionel Sambuc break;
673f4a2713aSLionel Sambuc case llvm::Triple::GNUEABI:
674f4a2713aSLionel Sambuc FloatABI = "softfp";
675f4a2713aSLionel Sambuc break;
676*0a6a1f1dSLionel Sambuc case llvm::Triple::EABIHF:
677*0a6a1f1dSLionel Sambuc FloatABI = "hard";
678*0a6a1f1dSLionel Sambuc break;
679f4a2713aSLionel Sambuc case llvm::Triple::EABI:
680f4a2713aSLionel Sambuc // EABI is always AAPCS, and if it was not marked 'hard', it's softfp
681f4a2713aSLionel Sambuc FloatABI = "softfp";
682f4a2713aSLionel Sambuc break;
683f4a2713aSLionel Sambuc case llvm::Triple::Android: {
684f4a2713aSLionel Sambuc std::string ArchName =
685*0a6a1f1dSLionel Sambuc arm::getLLVMArchSuffixForARM(arm::getARMTargetCPU(Args, Triple));
686f4a2713aSLionel Sambuc if (StringRef(ArchName).startswith("v7"))
687f4a2713aSLionel Sambuc FloatABI = "softfp";
688f4a2713aSLionel Sambuc else
689f4a2713aSLionel Sambuc FloatABI = "soft";
690f4a2713aSLionel Sambuc break;
691f4a2713aSLionel Sambuc }
692f4a2713aSLionel Sambuc default:
693f4a2713aSLionel Sambuc // Assume "soft", but warn the user we are guessing.
694f4a2713aSLionel Sambuc FloatABI = "soft";
695*0a6a1f1dSLionel Sambuc if (Triple.getOS() != llvm::Triple::UnknownOS ||
696*0a6a1f1dSLionel Sambuc !Triple.isOSBinFormatMachO())
697f4a2713aSLionel Sambuc D.Diag(diag::warn_drv_assuming_mfloat_abi_is) << "soft";
698f4a2713aSLionel Sambuc break;
699f4a2713aSLionel Sambuc }
700f4a2713aSLionel Sambuc }
701f4a2713aSLionel Sambuc }
702f4a2713aSLionel Sambuc
703f4a2713aSLionel Sambuc return FloatABI;
704f4a2713aSLionel Sambuc }
705f4a2713aSLionel Sambuc
getARMTargetFeatures(const Driver & D,const llvm::Triple & Triple,const ArgList & Args,std::vector<const char * > & Features,bool ForAS)706f4a2713aSLionel Sambuc static void getARMTargetFeatures(const Driver &D, const llvm::Triple &Triple,
707f4a2713aSLionel Sambuc const ArgList &Args,
708*0a6a1f1dSLionel Sambuc std::vector<const char *> &Features,
709*0a6a1f1dSLionel Sambuc bool ForAS) {
710*0a6a1f1dSLionel Sambuc StringRef FloatABI = tools::arm::getARMFloatABI(D, Args, Triple);
711*0a6a1f1dSLionel Sambuc if (!ForAS) {
712f4a2713aSLionel Sambuc // FIXME: Note, this is a hack, the LLVM backend doesn't actually use these
713f4a2713aSLionel Sambuc // yet (it uses the -mfloat-abi and -msoft-float options), and it is
714*0a6a1f1dSLionel Sambuc // stripped out by the ARM target. We should probably pass this a new
715*0a6a1f1dSLionel Sambuc // -target-option, which is handled by the -cc1/-cc1as invocation.
716*0a6a1f1dSLionel Sambuc //
717*0a6a1f1dSLionel Sambuc // FIXME2: For consistency, it would be ideal if we set up the target
718*0a6a1f1dSLionel Sambuc // machine state the same when using the frontend or the assembler. We don't
719*0a6a1f1dSLionel Sambuc // currently do that for the assembler, we pass the options directly to the
720*0a6a1f1dSLionel Sambuc // backend and never even instantiate the frontend TargetInfo. If we did,
721*0a6a1f1dSLionel Sambuc // and used its handleTargetFeatures hook, then we could ensure the
722*0a6a1f1dSLionel Sambuc // assembler and the frontend behave the same.
723*0a6a1f1dSLionel Sambuc
724f4a2713aSLionel Sambuc // Use software floating point operations?
725f4a2713aSLionel Sambuc if (FloatABI == "soft")
726f4a2713aSLionel Sambuc Features.push_back("+soft-float");
727f4a2713aSLionel Sambuc
728f4a2713aSLionel Sambuc // Use software floating point argument passing?
729f4a2713aSLionel Sambuc if (FloatABI != "hard")
730f4a2713aSLionel Sambuc Features.push_back("+soft-float-abi");
731*0a6a1f1dSLionel Sambuc }
732f4a2713aSLionel Sambuc
733f4a2713aSLionel Sambuc // Honor -mfpu=.
734f4a2713aSLionel Sambuc if (const Arg *A = Args.getLastArg(options::OPT_mfpu_EQ))
735f4a2713aSLionel Sambuc getARMFPUFeatures(D, A, Args, Features);
736f4a2713aSLionel Sambuc if (const Arg *A = Args.getLastArg(options::OPT_mhwdiv_EQ))
737f4a2713aSLionel Sambuc getARMHWDivFeatures(D, A, Args, Features);
738f4a2713aSLionel Sambuc
739f4a2713aSLionel Sambuc // Setting -msoft-float effectively disables NEON because of the GCC
740f4a2713aSLionel Sambuc // implementation, although the same isn't true of VFP or VFP3.
741*0a6a1f1dSLionel Sambuc if (FloatABI == "soft") {
742f4a2713aSLionel Sambuc Features.push_back("-neon");
743*0a6a1f1dSLionel Sambuc // Also need to explicitly disable features which imply NEON.
744*0a6a1f1dSLionel Sambuc Features.push_back("-crypto");
745*0a6a1f1dSLionel Sambuc }
746f4a2713aSLionel Sambuc
747f4a2713aSLionel Sambuc // En/disable crc
748f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_mcrc,
749f4a2713aSLionel Sambuc options::OPT_mnocrc)) {
750f4a2713aSLionel Sambuc if (A->getOption().matches(options::OPT_mcrc))
751f4a2713aSLionel Sambuc Features.push_back("+crc");
752f4a2713aSLionel Sambuc else
753f4a2713aSLionel Sambuc Features.push_back("-crc");
754f4a2713aSLionel Sambuc }
755f4a2713aSLionel Sambuc }
756f4a2713aSLionel Sambuc
AddARMTargetArgs(const ArgList & Args,ArgStringList & CmdArgs,bool KernelOrKext) const757f4a2713aSLionel Sambuc void Clang::AddARMTargetArgs(const ArgList &Args,
758f4a2713aSLionel Sambuc ArgStringList &CmdArgs,
759f4a2713aSLionel Sambuc bool KernelOrKext) const {
760f4a2713aSLionel Sambuc const Driver &D = getToolChain().getDriver();
761f4a2713aSLionel Sambuc // Get the effective triple, which takes into account the deployment target.
762f4a2713aSLionel Sambuc std::string TripleStr = getToolChain().ComputeEffectiveClangTriple(Args);
763f4a2713aSLionel Sambuc llvm::Triple Triple(TripleStr);
764*0a6a1f1dSLionel Sambuc std::string CPUName = arm::getARMTargetCPU(Args, Triple);
765f4a2713aSLionel Sambuc
766f4a2713aSLionel Sambuc // Select the ABI to use.
767f4a2713aSLionel Sambuc //
768f4a2713aSLionel Sambuc // FIXME: Support -meabi.
769*0a6a1f1dSLionel Sambuc // FIXME: Parts of this are duplicated in the backend, unify this somehow.
770*0a6a1f1dSLionel Sambuc const char *ABIName = nullptr;
771f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) {
772f4a2713aSLionel Sambuc ABIName = A->getValue();
773*0a6a1f1dSLionel Sambuc } else if (Triple.isOSBinFormatMachO()) {
774f4a2713aSLionel Sambuc // The backend is hardwired to assume AAPCS for M-class processors, ensure
775f4a2713aSLionel Sambuc // the frontend matches that.
776f4a2713aSLionel Sambuc if (Triple.getEnvironment() == llvm::Triple::EABI ||
777*0a6a1f1dSLionel Sambuc Triple.getOS() == llvm::Triple::UnknownOS ||
778f4a2713aSLionel Sambuc StringRef(CPUName).startswith("cortex-m")) {
779f4a2713aSLionel Sambuc ABIName = "aapcs";
780f4a2713aSLionel Sambuc } else {
781f4a2713aSLionel Sambuc ABIName = "apcs-gnu";
782f4a2713aSLionel Sambuc }
783*0a6a1f1dSLionel Sambuc } else if (Triple.isOSWindows()) {
784*0a6a1f1dSLionel Sambuc // FIXME: this is invalid for WindowsCE
785*0a6a1f1dSLionel Sambuc ABIName = "aapcs";
786f4a2713aSLionel Sambuc } else {
787f4a2713aSLionel Sambuc // Select the default based on the platform.
788f4a2713aSLionel Sambuc switch(Triple.getEnvironment()) {
789f4a2713aSLionel Sambuc case llvm::Triple::Android:
790f4a2713aSLionel Sambuc case llvm::Triple::GNUEABI:
791f4a2713aSLionel Sambuc case llvm::Triple::GNUEABIHF:
792f4a2713aSLionel Sambuc ABIName = "aapcs-linux";
793f4a2713aSLionel Sambuc break;
794*0a6a1f1dSLionel Sambuc case llvm::Triple::EABIHF:
795f4a2713aSLionel Sambuc case llvm::Triple::EABI:
796f4a2713aSLionel Sambuc ABIName = "aapcs";
797f4a2713aSLionel Sambuc break;
798f4a2713aSLionel Sambuc default:
799*0a6a1f1dSLionel Sambuc if (Triple.getOS() == llvm::Triple::NetBSD)
800f4a2713aSLionel Sambuc ABIName = "apcs-gnu";
801*0a6a1f1dSLionel Sambuc else
802*0a6a1f1dSLionel Sambuc ABIName = "aapcs";
803*0a6a1f1dSLionel Sambuc break;
804f4a2713aSLionel Sambuc }
805f4a2713aSLionel Sambuc }
806f4a2713aSLionel Sambuc CmdArgs.push_back("-target-abi");
807f4a2713aSLionel Sambuc CmdArgs.push_back(ABIName);
808f4a2713aSLionel Sambuc
809f4a2713aSLionel Sambuc // Determine floating point ABI from the options & target defaults.
810*0a6a1f1dSLionel Sambuc StringRef FloatABI = tools::arm::getARMFloatABI(D, Args, Triple);
811f4a2713aSLionel Sambuc if (FloatABI == "soft") {
812f4a2713aSLionel Sambuc // Floating point operations and argument passing are soft.
813f4a2713aSLionel Sambuc //
814f4a2713aSLionel Sambuc // FIXME: This changes CPP defines, we need -target-soft-float.
815f4a2713aSLionel Sambuc CmdArgs.push_back("-msoft-float");
816f4a2713aSLionel Sambuc CmdArgs.push_back("-mfloat-abi");
817f4a2713aSLionel Sambuc CmdArgs.push_back("soft");
818f4a2713aSLionel Sambuc } else if (FloatABI == "softfp") {
819f4a2713aSLionel Sambuc // Floating point operations are hard, but argument passing is soft.
820f4a2713aSLionel Sambuc CmdArgs.push_back("-mfloat-abi");
821f4a2713aSLionel Sambuc CmdArgs.push_back("soft");
822f4a2713aSLionel Sambuc } else {
823f4a2713aSLionel Sambuc // Floating point operations and argument passing are hard.
824f4a2713aSLionel Sambuc assert(FloatABI == "hard" && "Invalid float abi!");
825f4a2713aSLionel Sambuc CmdArgs.push_back("-mfloat-abi");
826f4a2713aSLionel Sambuc CmdArgs.push_back("hard");
827f4a2713aSLionel Sambuc }
828f4a2713aSLionel Sambuc
829f4a2713aSLionel Sambuc // Kernel code has more strict alignment requirements.
830f4a2713aSLionel Sambuc if (KernelOrKext) {
831f4a2713aSLionel Sambuc if (!Triple.isiOS() || Triple.isOSVersionLT(6)) {
832f4a2713aSLionel Sambuc CmdArgs.push_back("-backend-option");
833f4a2713aSLionel Sambuc CmdArgs.push_back("-arm-long-calls");
834f4a2713aSLionel Sambuc }
835f4a2713aSLionel Sambuc
836f4a2713aSLionel Sambuc CmdArgs.push_back("-backend-option");
837f4a2713aSLionel Sambuc CmdArgs.push_back("-arm-strict-align");
838f4a2713aSLionel Sambuc
839f4a2713aSLionel Sambuc // The kext linker doesn't know how to deal with movw/movt.
840f4a2713aSLionel Sambuc CmdArgs.push_back("-backend-option");
841f4a2713aSLionel Sambuc CmdArgs.push_back("-arm-use-movt=0");
842f4a2713aSLionel Sambuc }
843f4a2713aSLionel Sambuc
844*0a6a1f1dSLionel Sambuc // -mkernel implies -mstrict-align; don't add the redundant option.
845*0a6a1f1dSLionel Sambuc if (!KernelOrKext) {
846*0a6a1f1dSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_mno_unaligned_access,
847*0a6a1f1dSLionel Sambuc options::OPT_munaligned_access)) {
848*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-backend-option");
849*0a6a1f1dSLionel Sambuc if (A->getOption().matches(options::OPT_mno_unaligned_access))
850*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-arm-strict-align");
851*0a6a1f1dSLionel Sambuc else {
852*0a6a1f1dSLionel Sambuc if (Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v6m)
853*0a6a1f1dSLionel Sambuc D.Diag(diag::err_target_unsupported_unaligned) << "v6m";
854*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-arm-no-strict-align");
855*0a6a1f1dSLionel Sambuc }
856*0a6a1f1dSLionel Sambuc }
857*0a6a1f1dSLionel Sambuc }
858*0a6a1f1dSLionel Sambuc
859f4a2713aSLionel Sambuc // Setting -mno-global-merge disables the codegen global merge pass. Setting
860f4a2713aSLionel Sambuc // -mglobal-merge has no effect as the pass is enabled by default.
861f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_mglobal_merge,
862f4a2713aSLionel Sambuc options::OPT_mno_global_merge)) {
863f4a2713aSLionel Sambuc if (A->getOption().matches(options::OPT_mno_global_merge))
864f4a2713aSLionel Sambuc CmdArgs.push_back("-mno-global-merge");
865f4a2713aSLionel Sambuc }
866f4a2713aSLionel Sambuc
867f4a2713aSLionel Sambuc if (!Args.hasFlag(options::OPT_mimplicit_float,
868f4a2713aSLionel Sambuc options::OPT_mno_implicit_float,
869f4a2713aSLionel Sambuc true))
870f4a2713aSLionel Sambuc CmdArgs.push_back("-no-implicit-float");
871f4a2713aSLionel Sambuc
872f4a2713aSLionel Sambuc // llvm does not support reserving registers in general. There is support
873f4a2713aSLionel Sambuc // for reserving r9 on ARM though (defined as a platform-specific register
874f4a2713aSLionel Sambuc // in ARM EABI).
875f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_ffixed_r9)) {
876f4a2713aSLionel Sambuc CmdArgs.push_back("-backend-option");
877f4a2713aSLionel Sambuc CmdArgs.push_back("-arm-reserve-r9");
878f4a2713aSLionel Sambuc }
879f4a2713aSLionel Sambuc }
880f4a2713aSLionel Sambuc
881*0a6a1f1dSLionel Sambuc /// getAArch64TargetCPU - Get the (LLVM) name of the AArch64 cpu we are
882*0a6a1f1dSLionel Sambuc /// targeting.
getAArch64TargetCPU(const ArgList & Args)883*0a6a1f1dSLionel Sambuc static std::string getAArch64TargetCPU(const ArgList &Args) {
884*0a6a1f1dSLionel Sambuc Arg *A;
885*0a6a1f1dSLionel Sambuc std::string CPU;
886*0a6a1f1dSLionel Sambuc // If we have -mtune or -mcpu, use that.
887*0a6a1f1dSLionel Sambuc if ((A = Args.getLastArg(options::OPT_mtune_EQ))) {
888*0a6a1f1dSLionel Sambuc CPU = A->getValue();
889*0a6a1f1dSLionel Sambuc } else if ((A = Args.getLastArg(options::OPT_mcpu_EQ))) {
890*0a6a1f1dSLionel Sambuc StringRef Mcpu = A->getValue();
891*0a6a1f1dSLionel Sambuc CPU = Mcpu.split("+").first;
892*0a6a1f1dSLionel Sambuc }
893*0a6a1f1dSLionel Sambuc
894*0a6a1f1dSLionel Sambuc // Handle CPU name is 'native'.
895*0a6a1f1dSLionel Sambuc if (CPU == "native")
896*0a6a1f1dSLionel Sambuc return llvm::sys::getHostCPUName();
897*0a6a1f1dSLionel Sambuc else if (CPU.size())
898*0a6a1f1dSLionel Sambuc return CPU;
899*0a6a1f1dSLionel Sambuc
900*0a6a1f1dSLionel Sambuc // Make sure we pick "cyclone" if -arch is used.
901*0a6a1f1dSLionel Sambuc // FIXME: Should this be picked by checking the target triple instead?
902*0a6a1f1dSLionel Sambuc if (Args.getLastArg(options::OPT_arch))
903*0a6a1f1dSLionel Sambuc return "cyclone";
904*0a6a1f1dSLionel Sambuc
905*0a6a1f1dSLionel Sambuc return "generic";
906*0a6a1f1dSLionel Sambuc }
907*0a6a1f1dSLionel Sambuc
AddAArch64TargetArgs(const ArgList & Args,ArgStringList & CmdArgs) const908*0a6a1f1dSLionel Sambuc void Clang::AddAArch64TargetArgs(const ArgList &Args,
909*0a6a1f1dSLionel Sambuc ArgStringList &CmdArgs) const {
910*0a6a1f1dSLionel Sambuc std::string TripleStr = getToolChain().ComputeEffectiveClangTriple(Args);
911*0a6a1f1dSLionel Sambuc llvm::Triple Triple(TripleStr);
912*0a6a1f1dSLionel Sambuc
913*0a6a1f1dSLionel Sambuc if (!Args.hasFlag(options::OPT_mred_zone, options::OPT_mno_red_zone, true) ||
914*0a6a1f1dSLionel Sambuc Args.hasArg(options::OPT_mkernel) ||
915*0a6a1f1dSLionel Sambuc Args.hasArg(options::OPT_fapple_kext))
916*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-disable-red-zone");
917*0a6a1f1dSLionel Sambuc
918*0a6a1f1dSLionel Sambuc if (!Args.hasFlag(options::OPT_mimplicit_float,
919*0a6a1f1dSLionel Sambuc options::OPT_mno_implicit_float, true))
920*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-no-implicit-float");
921*0a6a1f1dSLionel Sambuc
922*0a6a1f1dSLionel Sambuc const char *ABIName = nullptr;
923*0a6a1f1dSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ))
924*0a6a1f1dSLionel Sambuc ABIName = A->getValue();
925*0a6a1f1dSLionel Sambuc else if (Triple.isOSDarwin())
926*0a6a1f1dSLionel Sambuc ABIName = "darwinpcs";
927*0a6a1f1dSLionel Sambuc else
928*0a6a1f1dSLionel Sambuc ABIName = "aapcs";
929*0a6a1f1dSLionel Sambuc
930*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-target-abi");
931*0a6a1f1dSLionel Sambuc CmdArgs.push_back(ABIName);
932*0a6a1f1dSLionel Sambuc
933*0a6a1f1dSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_mno_unaligned_access,
934*0a6a1f1dSLionel Sambuc options::OPT_munaligned_access)) {
935*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-backend-option");
936*0a6a1f1dSLionel Sambuc if (A->getOption().matches(options::OPT_mno_unaligned_access))
937*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-aarch64-strict-align");
938*0a6a1f1dSLionel Sambuc else
939*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-aarch64-no-strict-align");
940*0a6a1f1dSLionel Sambuc }
941*0a6a1f1dSLionel Sambuc
942*0a6a1f1dSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_mfix_cortex_a53_835769,
943*0a6a1f1dSLionel Sambuc options::OPT_mno_fix_cortex_a53_835769)) {
944*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-backend-option");
945*0a6a1f1dSLionel Sambuc if (A->getOption().matches(options::OPT_mfix_cortex_a53_835769))
946*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-aarch64-fix-cortex-a53-835769=1");
947*0a6a1f1dSLionel Sambuc else
948*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-aarch64-fix-cortex-a53-835769=0");
949*0a6a1f1dSLionel Sambuc } else if (Triple.getEnvironment() == llvm::Triple::Android) {
950*0a6a1f1dSLionel Sambuc // Enabled A53 errata (835769) workaround by default on android
951*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-backend-option");
952*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-aarch64-fix-cortex-a53-835769=1");
953*0a6a1f1dSLionel Sambuc }
954*0a6a1f1dSLionel Sambuc
955*0a6a1f1dSLionel Sambuc // Setting -mno-global-merge disables the codegen global merge pass. Setting
956*0a6a1f1dSLionel Sambuc // -mglobal-merge has no effect as the pass is enabled by default.
957*0a6a1f1dSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_mglobal_merge,
958*0a6a1f1dSLionel Sambuc options::OPT_mno_global_merge)) {
959*0a6a1f1dSLionel Sambuc if (A->getOption().matches(options::OPT_mno_global_merge))
960*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-mno-global-merge");
961*0a6a1f1dSLionel Sambuc }
962*0a6a1f1dSLionel Sambuc
963*0a6a1f1dSLionel Sambuc if (Args.hasArg(options::OPT_ffixed_x18)) {
964*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-backend-option");
965*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-aarch64-reserve-x18");
966*0a6a1f1dSLionel Sambuc }
967*0a6a1f1dSLionel Sambuc }
968*0a6a1f1dSLionel Sambuc
969f4a2713aSLionel Sambuc // Get CPU and ABI names. They are not independent
970f4a2713aSLionel Sambuc // so we have to calculate them together.
getMipsCPUAndABI(const ArgList & Args,const llvm::Triple & Triple,StringRef & CPUName,StringRef & ABIName)971*0a6a1f1dSLionel Sambuc void mips::getMipsCPUAndABI(const ArgList &Args,
972f4a2713aSLionel Sambuc const llvm::Triple &Triple,
973f4a2713aSLionel Sambuc StringRef &CPUName,
974f4a2713aSLionel Sambuc StringRef &ABIName) {
975*0a6a1f1dSLionel Sambuc const char *DefMips32CPU = "mips32r2";
976*0a6a1f1dSLionel Sambuc const char *DefMips64CPU = "mips64r2";
977*0a6a1f1dSLionel Sambuc
978*0a6a1f1dSLionel Sambuc // MIPS32r6 is the default for mips(el)?-img-linux-gnu and MIPS64r6 is the
979*0a6a1f1dSLionel Sambuc // default for mips64(el)?-img-linux-gnu.
980*0a6a1f1dSLionel Sambuc if (Triple.getVendor() == llvm::Triple::ImaginationTechnologies &&
981*0a6a1f1dSLionel Sambuc Triple.getEnvironment() == llvm::Triple::GNU) {
982*0a6a1f1dSLionel Sambuc DefMips32CPU = "mips32r6";
983*0a6a1f1dSLionel Sambuc DefMips64CPU = "mips64r6";
984*0a6a1f1dSLionel Sambuc }
985*0a6a1f1dSLionel Sambuc
986*0a6a1f1dSLionel Sambuc // MIPS3 is the default for mips64*-unknown-openbsd.
987*0a6a1f1dSLionel Sambuc if (Triple.getOS() == llvm::Triple::OpenBSD)
988*0a6a1f1dSLionel Sambuc DefMips64CPU = "mips3";
989f4a2713aSLionel Sambuc
990f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_march_EQ,
991f4a2713aSLionel Sambuc options::OPT_mcpu_EQ))
992f4a2713aSLionel Sambuc CPUName = A->getValue();
993f4a2713aSLionel Sambuc
994f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) {
995f4a2713aSLionel Sambuc ABIName = A->getValue();
996f4a2713aSLionel Sambuc // Convert a GNU style Mips ABI name to the name
997f4a2713aSLionel Sambuc // accepted by LLVM Mips backend.
998f4a2713aSLionel Sambuc ABIName = llvm::StringSwitch<llvm::StringRef>(ABIName)
999f4a2713aSLionel Sambuc .Case("32", "o32")
1000f4a2713aSLionel Sambuc .Case("64", "n64")
1001f4a2713aSLionel Sambuc .Default(ABIName);
1002f4a2713aSLionel Sambuc }
1003f4a2713aSLionel Sambuc
1004f4a2713aSLionel Sambuc // Setup default CPU and ABI names.
1005f4a2713aSLionel Sambuc if (CPUName.empty() && ABIName.empty()) {
1006f4a2713aSLionel Sambuc switch (Triple.getArch()) {
1007f4a2713aSLionel Sambuc default:
1008f4a2713aSLionel Sambuc llvm_unreachable("Unexpected triple arch name");
1009f4a2713aSLionel Sambuc case llvm::Triple::mips:
1010f4a2713aSLionel Sambuc case llvm::Triple::mipsel:
1011f4a2713aSLionel Sambuc CPUName = DefMips32CPU;
1012f4a2713aSLionel Sambuc break;
1013f4a2713aSLionel Sambuc case llvm::Triple::mips64:
1014f4a2713aSLionel Sambuc case llvm::Triple::mips64el:
1015f4a2713aSLionel Sambuc CPUName = DefMips64CPU;
1016f4a2713aSLionel Sambuc break;
1017f4a2713aSLionel Sambuc }
1018f4a2713aSLionel Sambuc }
1019f4a2713aSLionel Sambuc
1020*0a6a1f1dSLionel Sambuc if (ABIName.empty()) {
1021*0a6a1f1dSLionel Sambuc // Deduce ABI name from the target triple.
1022*0a6a1f1dSLionel Sambuc if (Triple.getArch() == llvm::Triple::mips ||
1023*0a6a1f1dSLionel Sambuc Triple.getArch() == llvm::Triple::mipsel)
1024*0a6a1f1dSLionel Sambuc ABIName = "o32";
1025*0a6a1f1dSLionel Sambuc else
1026*0a6a1f1dSLionel Sambuc ABIName = "n64";
1027*0a6a1f1dSLionel Sambuc }
1028*0a6a1f1dSLionel Sambuc
1029*0a6a1f1dSLionel Sambuc if (CPUName.empty()) {
1030f4a2713aSLionel Sambuc // Deduce CPU name from ABI name.
1031f4a2713aSLionel Sambuc CPUName = llvm::StringSwitch<const char *>(ABIName)
1032*0a6a1f1dSLionel Sambuc .Cases("o32", "eabi", DefMips32CPU)
1033*0a6a1f1dSLionel Sambuc .Cases("n32", "n64", DefMips64CPU)
1034f4a2713aSLionel Sambuc .Default("");
1035f4a2713aSLionel Sambuc }
1036f4a2713aSLionel Sambuc
1037*0a6a1f1dSLionel Sambuc // FIXME: Warn on inconsistent use of -march and -mabi.
1038f4a2713aSLionel Sambuc }
1039f4a2713aSLionel Sambuc
1040f4a2713aSLionel Sambuc // Convert ABI name to the GNU tools acceptable variant.
getGnuCompatibleMipsABIName(StringRef ABI)1041f4a2713aSLionel Sambuc static StringRef getGnuCompatibleMipsABIName(StringRef ABI) {
1042f4a2713aSLionel Sambuc return llvm::StringSwitch<llvm::StringRef>(ABI)
1043f4a2713aSLionel Sambuc .Case("o32", "32")
1044f4a2713aSLionel Sambuc .Case("n64", "64")
1045f4a2713aSLionel Sambuc .Default(ABI);
1046f4a2713aSLionel Sambuc }
1047f4a2713aSLionel Sambuc
1048f4a2713aSLionel Sambuc // Select the MIPS float ABI as determined by -msoft-float, -mhard-float,
1049f4a2713aSLionel Sambuc // and -mfloat-abi=.
getMipsFloatABI(const Driver & D,const ArgList & Args)1050f4a2713aSLionel Sambuc static StringRef getMipsFloatABI(const Driver &D, const ArgList &Args) {
1051f4a2713aSLionel Sambuc StringRef FloatABI;
1052f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_msoft_float,
1053f4a2713aSLionel Sambuc options::OPT_mhard_float,
1054f4a2713aSLionel Sambuc options::OPT_mfloat_abi_EQ)) {
1055f4a2713aSLionel Sambuc if (A->getOption().matches(options::OPT_msoft_float))
1056f4a2713aSLionel Sambuc FloatABI = "soft";
1057f4a2713aSLionel Sambuc else if (A->getOption().matches(options::OPT_mhard_float))
1058f4a2713aSLionel Sambuc FloatABI = "hard";
1059f4a2713aSLionel Sambuc else {
1060f4a2713aSLionel Sambuc FloatABI = A->getValue();
1061f4a2713aSLionel Sambuc if (FloatABI != "soft" && FloatABI != "hard") {
1062f4a2713aSLionel Sambuc D.Diag(diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);
1063f4a2713aSLionel Sambuc FloatABI = "hard";
1064f4a2713aSLionel Sambuc }
1065f4a2713aSLionel Sambuc }
1066f4a2713aSLionel Sambuc }
1067f4a2713aSLionel Sambuc
1068f4a2713aSLionel Sambuc // If unspecified, choose the default based on the platform.
1069f4a2713aSLionel Sambuc if (FloatABI.empty()) {
1070f4a2713aSLionel Sambuc // Assume "hard", because it's a default value used by gcc.
1071f4a2713aSLionel Sambuc // When we start to recognize specific target MIPS processors,
1072f4a2713aSLionel Sambuc // we will be able to select the default more correctly.
1073f4a2713aSLionel Sambuc FloatABI = "hard";
1074f4a2713aSLionel Sambuc }
1075f4a2713aSLionel Sambuc
1076f4a2713aSLionel Sambuc return FloatABI;
1077f4a2713aSLionel Sambuc }
1078f4a2713aSLionel Sambuc
AddTargetFeature(const ArgList & Args,std::vector<const char * > & Features,OptSpecifier OnOpt,OptSpecifier OffOpt,StringRef FeatureName)1079f4a2713aSLionel Sambuc static void AddTargetFeature(const ArgList &Args,
1080f4a2713aSLionel Sambuc std::vector<const char *> &Features,
1081f4a2713aSLionel Sambuc OptSpecifier OnOpt, OptSpecifier OffOpt,
1082f4a2713aSLionel Sambuc StringRef FeatureName) {
1083f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(OnOpt, OffOpt)) {
1084f4a2713aSLionel Sambuc if (A->getOption().matches(OnOpt))
1085f4a2713aSLionel Sambuc Features.push_back(Args.MakeArgString("+" + FeatureName));
1086f4a2713aSLionel Sambuc else
1087f4a2713aSLionel Sambuc Features.push_back(Args.MakeArgString("-" + FeatureName));
1088f4a2713aSLionel Sambuc }
1089f4a2713aSLionel Sambuc }
1090f4a2713aSLionel Sambuc
getMIPSTargetFeatures(const Driver & D,const llvm::Triple & Triple,const ArgList & Args,std::vector<const char * > & Features)1091*0a6a1f1dSLionel Sambuc static void getMIPSTargetFeatures(const Driver &D, const llvm::Triple &Triple,
1092*0a6a1f1dSLionel Sambuc const ArgList &Args,
1093f4a2713aSLionel Sambuc std::vector<const char *> &Features) {
1094*0a6a1f1dSLionel Sambuc StringRef CPUName;
1095*0a6a1f1dSLionel Sambuc StringRef ABIName;
1096*0a6a1f1dSLionel Sambuc mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
1097*0a6a1f1dSLionel Sambuc ABIName = getGnuCompatibleMipsABIName(ABIName);
1098*0a6a1f1dSLionel Sambuc
1099*0a6a1f1dSLionel Sambuc // Always override the backend's default ABI.
1100*0a6a1f1dSLionel Sambuc std::string ABIFeature = llvm::StringSwitch<StringRef>(ABIName)
1101*0a6a1f1dSLionel Sambuc .Case("32", "+o32")
1102*0a6a1f1dSLionel Sambuc .Case("n32", "+n32")
1103*0a6a1f1dSLionel Sambuc .Case("64", "+n64")
1104*0a6a1f1dSLionel Sambuc .Case("eabi", "+eabi")
1105*0a6a1f1dSLionel Sambuc .Default(("+" + ABIName).str());
1106*0a6a1f1dSLionel Sambuc Features.push_back("-o32");
1107*0a6a1f1dSLionel Sambuc Features.push_back("-n64");
1108*0a6a1f1dSLionel Sambuc Features.push_back(Args.MakeArgString(ABIFeature));
1109*0a6a1f1dSLionel Sambuc
1110*0a6a1f1dSLionel Sambuc AddTargetFeature(Args, Features, options::OPT_mno_abicalls,
1111*0a6a1f1dSLionel Sambuc options::OPT_mabicalls, "noabicalls");
1112*0a6a1f1dSLionel Sambuc
1113f4a2713aSLionel Sambuc StringRef FloatABI = getMipsFloatABI(D, Args);
1114*0a6a1f1dSLionel Sambuc if (FloatABI == "soft") {
1115f4a2713aSLionel Sambuc // FIXME: Note, this is a hack. We need to pass the selected float
1116f4a2713aSLionel Sambuc // mode to the MipsTargetInfoBase to define appropriate macros there.
1117f4a2713aSLionel Sambuc // Now it is the only method.
1118f4a2713aSLionel Sambuc Features.push_back("+soft-float");
1119f4a2713aSLionel Sambuc }
1120f4a2713aSLionel Sambuc
1121f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_mnan_EQ)) {
1122*0a6a1f1dSLionel Sambuc StringRef Val = StringRef(A->getValue());
1123*0a6a1f1dSLionel Sambuc if (Val == "2008")
1124f4a2713aSLionel Sambuc Features.push_back("+nan2008");
1125*0a6a1f1dSLionel Sambuc else if (Val == "legacy")
1126*0a6a1f1dSLionel Sambuc Features.push_back("-nan2008");
1127*0a6a1f1dSLionel Sambuc else
1128*0a6a1f1dSLionel Sambuc D.Diag(diag::err_drv_unsupported_option_argument)
1129*0a6a1f1dSLionel Sambuc << A->getOption().getName() << Val;
1130f4a2713aSLionel Sambuc }
1131f4a2713aSLionel Sambuc
1132f4a2713aSLionel Sambuc AddTargetFeature(Args, Features, options::OPT_msingle_float,
1133f4a2713aSLionel Sambuc options::OPT_mdouble_float, "single-float");
1134f4a2713aSLionel Sambuc AddTargetFeature(Args, Features, options::OPT_mips16, options::OPT_mno_mips16,
1135f4a2713aSLionel Sambuc "mips16");
1136f4a2713aSLionel Sambuc AddTargetFeature(Args, Features, options::OPT_mmicromips,
1137f4a2713aSLionel Sambuc options::OPT_mno_micromips, "micromips");
1138f4a2713aSLionel Sambuc AddTargetFeature(Args, Features, options::OPT_mdsp, options::OPT_mno_dsp,
1139f4a2713aSLionel Sambuc "dsp");
1140f4a2713aSLionel Sambuc AddTargetFeature(Args, Features, options::OPT_mdspr2, options::OPT_mno_dspr2,
1141f4a2713aSLionel Sambuc "dspr2");
1142f4a2713aSLionel Sambuc AddTargetFeature(Args, Features, options::OPT_mmsa, options::OPT_mno_msa,
1143f4a2713aSLionel Sambuc "msa");
1144*0a6a1f1dSLionel Sambuc
1145*0a6a1f1dSLionel Sambuc // Add the last -mfp32/-mfpxx/-mfp64 or if none are given and the ABI is O32
1146*0a6a1f1dSLionel Sambuc // pass -mfpxx
1147*0a6a1f1dSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_mfp32, options::OPT_mfpxx,
1148*0a6a1f1dSLionel Sambuc options::OPT_mfp64)) {
1149*0a6a1f1dSLionel Sambuc if (A->getOption().matches(options::OPT_mfp32))
1150*0a6a1f1dSLionel Sambuc Features.push_back(Args.MakeArgString("-fp64"));
1151*0a6a1f1dSLionel Sambuc else if (A->getOption().matches(options::OPT_mfpxx)) {
1152*0a6a1f1dSLionel Sambuc Features.push_back(Args.MakeArgString("+fpxx"));
1153*0a6a1f1dSLionel Sambuc Features.push_back(Args.MakeArgString("+nooddspreg"));
1154*0a6a1f1dSLionel Sambuc } else
1155*0a6a1f1dSLionel Sambuc Features.push_back(Args.MakeArgString("+fp64"));
1156*0a6a1f1dSLionel Sambuc } else if (mips::isFPXXDefault(Triple, CPUName, ABIName)) {
1157*0a6a1f1dSLionel Sambuc Features.push_back(Args.MakeArgString("+fpxx"));
1158*0a6a1f1dSLionel Sambuc Features.push_back(Args.MakeArgString("+nooddspreg"));
1159*0a6a1f1dSLionel Sambuc }
1160*0a6a1f1dSLionel Sambuc
1161*0a6a1f1dSLionel Sambuc AddTargetFeature(Args, Features, options::OPT_mno_odd_spreg,
1162*0a6a1f1dSLionel Sambuc options::OPT_modd_spreg, "nooddspreg");
1163f4a2713aSLionel Sambuc }
1164f4a2713aSLionel Sambuc
AddMIPSTargetArgs(const ArgList & Args,ArgStringList & CmdArgs) const1165f4a2713aSLionel Sambuc void Clang::AddMIPSTargetArgs(const ArgList &Args,
1166f4a2713aSLionel Sambuc ArgStringList &CmdArgs) const {
1167f4a2713aSLionel Sambuc const Driver &D = getToolChain().getDriver();
1168f4a2713aSLionel Sambuc StringRef CPUName;
1169f4a2713aSLionel Sambuc StringRef ABIName;
1170f4a2713aSLionel Sambuc const llvm::Triple &Triple = getToolChain().getTriple();
1171*0a6a1f1dSLionel Sambuc mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
1172f4a2713aSLionel Sambuc
1173f4a2713aSLionel Sambuc CmdArgs.push_back("-target-abi");
1174f4a2713aSLionel Sambuc CmdArgs.push_back(ABIName.data());
1175f4a2713aSLionel Sambuc
1176f4a2713aSLionel Sambuc StringRef FloatABI = getMipsFloatABI(D, Args);
1177f4a2713aSLionel Sambuc
1178*0a6a1f1dSLionel Sambuc if (FloatABI == "soft") {
1179f4a2713aSLionel Sambuc // Floating point operations and argument passing are soft.
1180f4a2713aSLionel Sambuc CmdArgs.push_back("-msoft-float");
1181f4a2713aSLionel Sambuc CmdArgs.push_back("-mfloat-abi");
1182f4a2713aSLionel Sambuc CmdArgs.push_back("soft");
1183f4a2713aSLionel Sambuc }
1184f4a2713aSLionel Sambuc else {
1185f4a2713aSLionel Sambuc // Floating point operations and argument passing are hard.
1186f4a2713aSLionel Sambuc assert(FloatABI == "hard" && "Invalid float abi!");
1187f4a2713aSLionel Sambuc CmdArgs.push_back("-mfloat-abi");
1188f4a2713aSLionel Sambuc CmdArgs.push_back("hard");
1189f4a2713aSLionel Sambuc }
1190f4a2713aSLionel Sambuc
1191f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_mxgot, options::OPT_mno_xgot)) {
1192f4a2713aSLionel Sambuc if (A->getOption().matches(options::OPT_mxgot)) {
1193f4a2713aSLionel Sambuc CmdArgs.push_back("-mllvm");
1194f4a2713aSLionel Sambuc CmdArgs.push_back("-mxgot");
1195f4a2713aSLionel Sambuc }
1196f4a2713aSLionel Sambuc }
1197f4a2713aSLionel Sambuc
1198f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_mldc1_sdc1,
1199f4a2713aSLionel Sambuc options::OPT_mno_ldc1_sdc1)) {
1200f4a2713aSLionel Sambuc if (A->getOption().matches(options::OPT_mno_ldc1_sdc1)) {
1201f4a2713aSLionel Sambuc CmdArgs.push_back("-mllvm");
1202f4a2713aSLionel Sambuc CmdArgs.push_back("-mno-ldc1-sdc1");
1203f4a2713aSLionel Sambuc }
1204f4a2713aSLionel Sambuc }
1205f4a2713aSLionel Sambuc
1206f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_mcheck_zero_division,
1207f4a2713aSLionel Sambuc options::OPT_mno_check_zero_division)) {
1208f4a2713aSLionel Sambuc if (A->getOption().matches(options::OPT_mno_check_zero_division)) {
1209f4a2713aSLionel Sambuc CmdArgs.push_back("-mllvm");
1210f4a2713aSLionel Sambuc CmdArgs.push_back("-mno-check-zero-division");
1211f4a2713aSLionel Sambuc }
1212f4a2713aSLionel Sambuc }
1213f4a2713aSLionel Sambuc
1214f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_G)) {
1215f4a2713aSLionel Sambuc StringRef v = A->getValue();
1216f4a2713aSLionel Sambuc CmdArgs.push_back("-mllvm");
1217f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString("-mips-ssection-threshold=" + v));
1218f4a2713aSLionel Sambuc A->claim();
1219f4a2713aSLionel Sambuc }
1220f4a2713aSLionel Sambuc }
1221f4a2713aSLionel Sambuc
1222f4a2713aSLionel Sambuc /// getPPCTargetCPU - Get the (LLVM) name of the PowerPC cpu we are targeting.
getPPCTargetCPU(const ArgList & Args)1223f4a2713aSLionel Sambuc static std::string getPPCTargetCPU(const ArgList &Args) {
1224f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
1225f4a2713aSLionel Sambuc StringRef CPUName = A->getValue();
1226f4a2713aSLionel Sambuc
1227f4a2713aSLionel Sambuc if (CPUName == "native") {
1228f4a2713aSLionel Sambuc std::string CPU = llvm::sys::getHostCPUName();
1229f4a2713aSLionel Sambuc if (!CPU.empty() && CPU != "generic")
1230f4a2713aSLionel Sambuc return CPU;
1231f4a2713aSLionel Sambuc else
1232f4a2713aSLionel Sambuc return "";
1233f4a2713aSLionel Sambuc }
1234f4a2713aSLionel Sambuc
1235f4a2713aSLionel Sambuc return llvm::StringSwitch<const char *>(CPUName)
1236f4a2713aSLionel Sambuc .Case("common", "generic")
1237f4a2713aSLionel Sambuc .Case("440", "440")
1238f4a2713aSLionel Sambuc .Case("440fp", "440")
1239f4a2713aSLionel Sambuc .Case("450", "450")
1240f4a2713aSLionel Sambuc .Case("601", "601")
1241f4a2713aSLionel Sambuc .Case("602", "602")
1242f4a2713aSLionel Sambuc .Case("603", "603")
1243f4a2713aSLionel Sambuc .Case("603e", "603e")
1244f4a2713aSLionel Sambuc .Case("603ev", "603ev")
1245f4a2713aSLionel Sambuc .Case("604", "604")
1246f4a2713aSLionel Sambuc .Case("604e", "604e")
1247f4a2713aSLionel Sambuc .Case("620", "620")
1248f4a2713aSLionel Sambuc .Case("630", "pwr3")
1249f4a2713aSLionel Sambuc .Case("G3", "g3")
1250f4a2713aSLionel Sambuc .Case("7400", "7400")
1251f4a2713aSLionel Sambuc .Case("G4", "g4")
1252f4a2713aSLionel Sambuc .Case("7450", "7450")
1253f4a2713aSLionel Sambuc .Case("G4+", "g4+")
1254f4a2713aSLionel Sambuc .Case("750", "750")
1255f4a2713aSLionel Sambuc .Case("970", "970")
1256f4a2713aSLionel Sambuc .Case("G5", "g5")
1257f4a2713aSLionel Sambuc .Case("a2", "a2")
1258f4a2713aSLionel Sambuc .Case("a2q", "a2q")
1259f4a2713aSLionel Sambuc .Case("e500mc", "e500mc")
1260f4a2713aSLionel Sambuc .Case("e5500", "e5500")
1261f4a2713aSLionel Sambuc .Case("power3", "pwr3")
1262f4a2713aSLionel Sambuc .Case("power4", "pwr4")
1263f4a2713aSLionel Sambuc .Case("power5", "pwr5")
1264f4a2713aSLionel Sambuc .Case("power5x", "pwr5x")
1265f4a2713aSLionel Sambuc .Case("power6", "pwr6")
1266f4a2713aSLionel Sambuc .Case("power6x", "pwr6x")
1267f4a2713aSLionel Sambuc .Case("power7", "pwr7")
1268*0a6a1f1dSLionel Sambuc .Case("power8", "pwr8")
1269f4a2713aSLionel Sambuc .Case("pwr3", "pwr3")
1270f4a2713aSLionel Sambuc .Case("pwr4", "pwr4")
1271f4a2713aSLionel Sambuc .Case("pwr5", "pwr5")
1272f4a2713aSLionel Sambuc .Case("pwr5x", "pwr5x")
1273f4a2713aSLionel Sambuc .Case("pwr6", "pwr6")
1274f4a2713aSLionel Sambuc .Case("pwr6x", "pwr6x")
1275f4a2713aSLionel Sambuc .Case("pwr7", "pwr7")
1276*0a6a1f1dSLionel Sambuc .Case("pwr8", "pwr8")
1277f4a2713aSLionel Sambuc .Case("powerpc", "ppc")
1278f4a2713aSLionel Sambuc .Case("powerpc64", "ppc64")
1279f4a2713aSLionel Sambuc .Case("powerpc64le", "ppc64le")
1280f4a2713aSLionel Sambuc .Default("");
1281f4a2713aSLionel Sambuc }
1282f4a2713aSLionel Sambuc
1283f4a2713aSLionel Sambuc return "";
1284f4a2713aSLionel Sambuc }
1285f4a2713aSLionel Sambuc
getPPCTargetFeatures(const ArgList & Args,std::vector<const char * > & Features)1286f4a2713aSLionel Sambuc static void getPPCTargetFeatures(const ArgList &Args,
1287f4a2713aSLionel Sambuc std::vector<const char *> &Features) {
1288f4a2713aSLionel Sambuc for (arg_iterator it = Args.filtered_begin(options::OPT_m_ppc_Features_Group),
1289f4a2713aSLionel Sambuc ie = Args.filtered_end();
1290f4a2713aSLionel Sambuc it != ie; ++it) {
1291f4a2713aSLionel Sambuc StringRef Name = (*it)->getOption().getName();
1292f4a2713aSLionel Sambuc (*it)->claim();
1293f4a2713aSLionel Sambuc
1294f4a2713aSLionel Sambuc // Skip over "-m".
1295f4a2713aSLionel Sambuc assert(Name.startswith("m") && "Invalid feature name.");
1296f4a2713aSLionel Sambuc Name = Name.substr(1);
1297f4a2713aSLionel Sambuc
1298f4a2713aSLionel Sambuc bool IsNegative = Name.startswith("no-");
1299f4a2713aSLionel Sambuc if (IsNegative)
1300f4a2713aSLionel Sambuc Name = Name.substr(3);
1301f4a2713aSLionel Sambuc
1302f4a2713aSLionel Sambuc // Note that gcc calls this mfcrf and LLVM calls this mfocrf so we
1303f4a2713aSLionel Sambuc // pass the correct option to the backend while calling the frontend
1304f4a2713aSLionel Sambuc // option the same.
1305f4a2713aSLionel Sambuc // TODO: Change the LLVM backend option maybe?
1306f4a2713aSLionel Sambuc if (Name == "mfcrf")
1307f4a2713aSLionel Sambuc Name = "mfocrf";
1308f4a2713aSLionel Sambuc
1309f4a2713aSLionel Sambuc Features.push_back(Args.MakeArgString((IsNegative ? "-" : "+") + Name));
1310f4a2713aSLionel Sambuc }
1311f4a2713aSLionel Sambuc
1312f4a2713aSLionel Sambuc // Altivec is a bit weird, allow overriding of the Altivec feature here.
1313f4a2713aSLionel Sambuc AddTargetFeature(Args, Features, options::OPT_faltivec,
1314f4a2713aSLionel Sambuc options::OPT_fno_altivec, "altivec");
1315f4a2713aSLionel Sambuc }
1316f4a2713aSLionel Sambuc
AddPPCTargetArgs(const ArgList & Args,ArgStringList & CmdArgs) const1317*0a6a1f1dSLionel Sambuc void Clang::AddPPCTargetArgs(const ArgList &Args,
1318*0a6a1f1dSLionel Sambuc ArgStringList &CmdArgs) const {
1319*0a6a1f1dSLionel Sambuc // Select the ABI to use.
1320*0a6a1f1dSLionel Sambuc const char *ABIName = nullptr;
1321*0a6a1f1dSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) {
1322*0a6a1f1dSLionel Sambuc ABIName = A->getValue();
1323*0a6a1f1dSLionel Sambuc } else if (getToolChain().getTriple().isOSLinux())
1324*0a6a1f1dSLionel Sambuc switch(getToolChain().getArch()) {
1325*0a6a1f1dSLionel Sambuc case llvm::Triple::ppc64:
1326*0a6a1f1dSLionel Sambuc ABIName = "elfv1";
1327*0a6a1f1dSLionel Sambuc break;
1328*0a6a1f1dSLionel Sambuc case llvm::Triple::ppc64le:
1329*0a6a1f1dSLionel Sambuc ABIName = "elfv2";
1330*0a6a1f1dSLionel Sambuc break;
1331*0a6a1f1dSLionel Sambuc default:
1332*0a6a1f1dSLionel Sambuc break;
1333*0a6a1f1dSLionel Sambuc }
1334*0a6a1f1dSLionel Sambuc
1335*0a6a1f1dSLionel Sambuc if (ABIName) {
1336*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-target-abi");
1337*0a6a1f1dSLionel Sambuc CmdArgs.push_back(ABIName);
1338*0a6a1f1dSLionel Sambuc }
1339*0a6a1f1dSLionel Sambuc }
1340*0a6a1f1dSLionel Sambuc
hasPPCAbiArg(const ArgList & Args,const char * Value)1341*0a6a1f1dSLionel Sambuc bool ppc::hasPPCAbiArg(const ArgList &Args, const char *Value) {
1342*0a6a1f1dSLionel Sambuc Arg *A = Args.getLastArg(options::OPT_mabi_EQ);
1343*0a6a1f1dSLionel Sambuc return A && (A->getValue() == StringRef(Value));
1344*0a6a1f1dSLionel Sambuc }
1345*0a6a1f1dSLionel Sambuc
1346f4a2713aSLionel Sambuc /// Get the (LLVM) name of the R600 gpu we are targeting.
getR600TargetGPU(const ArgList & Args)1347f4a2713aSLionel Sambuc static std::string getR600TargetGPU(const ArgList &Args) {
1348f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
1349f4a2713aSLionel Sambuc const char *GPUName = A->getValue();
1350f4a2713aSLionel Sambuc return llvm::StringSwitch<const char *>(GPUName)
1351f4a2713aSLionel Sambuc .Cases("rv630", "rv635", "r600")
1352f4a2713aSLionel Sambuc .Cases("rv610", "rv620", "rs780", "rs880")
1353f4a2713aSLionel Sambuc .Case("rv740", "rv770")
1354f4a2713aSLionel Sambuc .Case("palm", "cedar")
1355f4a2713aSLionel Sambuc .Cases("sumo", "sumo2", "sumo")
1356f4a2713aSLionel Sambuc .Case("hemlock", "cypress")
1357f4a2713aSLionel Sambuc .Case("aruba", "cayman")
1358f4a2713aSLionel Sambuc .Default(GPUName);
1359f4a2713aSLionel Sambuc }
1360f4a2713aSLionel Sambuc return "";
1361f4a2713aSLionel Sambuc }
1362f4a2713aSLionel Sambuc
getSparcTargetFeatures(const ArgList & Args,std::vector<const char * > & Features)1363f4a2713aSLionel Sambuc static void getSparcTargetFeatures(const ArgList &Args,
1364*0a6a1f1dSLionel Sambuc std::vector<const char *> &Features) {
1365f4a2713aSLionel Sambuc bool SoftFloatABI = true;
1366f4a2713aSLionel Sambuc if (Arg *A =
1367f4a2713aSLionel Sambuc Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float)) {
1368f4a2713aSLionel Sambuc if (A->getOption().matches(options::OPT_mhard_float))
1369f4a2713aSLionel Sambuc SoftFloatABI = false;
1370f4a2713aSLionel Sambuc }
1371f4a2713aSLionel Sambuc if (SoftFloatABI)
1372f4a2713aSLionel Sambuc Features.push_back("+soft-float");
1373f4a2713aSLionel Sambuc }
1374f4a2713aSLionel Sambuc
AddSparcTargetArgs(const ArgList & Args,ArgStringList & CmdArgs) const1375f4a2713aSLionel Sambuc void Clang::AddSparcTargetArgs(const ArgList &Args,
1376f4a2713aSLionel Sambuc ArgStringList &CmdArgs) const {
1377f4a2713aSLionel Sambuc const Driver &D = getToolChain().getDriver();
1378f4a2713aSLionel Sambuc
1379*0a6a1f1dSLionel Sambuc // Select the float ABI as determined by -msoft-float and -mhard-float.
1380f4a2713aSLionel Sambuc StringRef FloatABI;
1381f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_msoft_float,
1382f4a2713aSLionel Sambuc options::OPT_mhard_float)) {
1383f4a2713aSLionel Sambuc if (A->getOption().matches(options::OPT_msoft_float))
1384f4a2713aSLionel Sambuc FloatABI = "soft";
1385f4a2713aSLionel Sambuc else if (A->getOption().matches(options::OPT_mhard_float))
1386f4a2713aSLionel Sambuc FloatABI = "hard";
1387f4a2713aSLionel Sambuc }
1388f4a2713aSLionel Sambuc
1389f4a2713aSLionel Sambuc // If unspecified, choose the default based on the platform.
1390f4a2713aSLionel Sambuc if (FloatABI.empty()) {
1391f4a2713aSLionel Sambuc // Assume "soft", but warn the user we are guessing.
1392f4a2713aSLionel Sambuc FloatABI = "soft";
1393f4a2713aSLionel Sambuc D.Diag(diag::warn_drv_assuming_mfloat_abi_is) << "soft";
1394f4a2713aSLionel Sambuc }
1395f4a2713aSLionel Sambuc
1396f4a2713aSLionel Sambuc if (FloatABI == "soft") {
1397f4a2713aSLionel Sambuc // Floating point operations and argument passing are soft.
1398f4a2713aSLionel Sambuc //
1399f4a2713aSLionel Sambuc // FIXME: This changes CPP defines, we need -target-soft-float.
1400f4a2713aSLionel Sambuc CmdArgs.push_back("-msoft-float");
1401f4a2713aSLionel Sambuc } else {
1402f4a2713aSLionel Sambuc assert(FloatABI == "hard" && "Invalid float abi!");
1403f4a2713aSLionel Sambuc CmdArgs.push_back("-mhard-float");
1404f4a2713aSLionel Sambuc }
1405f4a2713aSLionel Sambuc }
1406f4a2713aSLionel Sambuc
getSystemZTargetCPU(const ArgList & Args)1407f4a2713aSLionel Sambuc static const char *getSystemZTargetCPU(const ArgList &Args) {
1408f4a2713aSLionel Sambuc if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
1409f4a2713aSLionel Sambuc return A->getValue();
1410f4a2713aSLionel Sambuc return "z10";
1411f4a2713aSLionel Sambuc }
1412f4a2713aSLionel Sambuc
getX86TargetCPU(const ArgList & Args,const llvm::Triple & Triple)1413f4a2713aSLionel Sambuc static const char *getX86TargetCPU(const ArgList &Args,
1414f4a2713aSLionel Sambuc const llvm::Triple &Triple) {
1415f4a2713aSLionel Sambuc if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
1416f4a2713aSLionel Sambuc if (StringRef(A->getValue()) != "native") {
1417f4a2713aSLionel Sambuc if (Triple.isOSDarwin() && Triple.getArchName() == "x86_64h")
1418f4a2713aSLionel Sambuc return "core-avx2";
1419f4a2713aSLionel Sambuc
1420f4a2713aSLionel Sambuc return A->getValue();
1421f4a2713aSLionel Sambuc }
1422f4a2713aSLionel Sambuc
1423f4a2713aSLionel Sambuc // FIXME: Reject attempts to use -march=native unless the target matches
1424f4a2713aSLionel Sambuc // the host.
1425f4a2713aSLionel Sambuc //
1426f4a2713aSLionel Sambuc // FIXME: We should also incorporate the detected target features for use
1427f4a2713aSLionel Sambuc // with -native.
1428f4a2713aSLionel Sambuc std::string CPU = llvm::sys::getHostCPUName();
1429f4a2713aSLionel Sambuc if (!CPU.empty() && CPU != "generic")
1430f4a2713aSLionel Sambuc return Args.MakeArgString(CPU);
1431f4a2713aSLionel Sambuc }
1432f4a2713aSLionel Sambuc
1433f4a2713aSLionel Sambuc // Select the default CPU if none was given (or detection failed).
1434f4a2713aSLionel Sambuc
1435f4a2713aSLionel Sambuc if (Triple.getArch() != llvm::Triple::x86_64 &&
1436f4a2713aSLionel Sambuc Triple.getArch() != llvm::Triple::x86)
1437*0a6a1f1dSLionel Sambuc return nullptr; // This routine is only handling x86 targets.
1438f4a2713aSLionel Sambuc
1439f4a2713aSLionel Sambuc bool Is64Bit = Triple.getArch() == llvm::Triple::x86_64;
1440f4a2713aSLionel Sambuc
1441f4a2713aSLionel Sambuc // FIXME: Need target hooks.
1442f4a2713aSLionel Sambuc if (Triple.isOSDarwin()) {
1443f4a2713aSLionel Sambuc if (Triple.getArchName() == "x86_64h")
1444f4a2713aSLionel Sambuc return "core-avx2";
1445f4a2713aSLionel Sambuc return Is64Bit ? "core2" : "yonah";
1446f4a2713aSLionel Sambuc }
1447f4a2713aSLionel Sambuc
1448*0a6a1f1dSLionel Sambuc // On Android use targets compatible with gcc
1449f4a2713aSLionel Sambuc if (Triple.getEnvironment() == llvm::Triple::Android)
1450*0a6a1f1dSLionel Sambuc return Is64Bit ? "x86-64" : "i686";
1451f4a2713aSLionel Sambuc
1452f4a2713aSLionel Sambuc // Everything else goes to x86-64 in 64-bit mode.
1453f4a2713aSLionel Sambuc if (Is64Bit)
1454f4a2713aSLionel Sambuc return "x86-64";
1455f4a2713aSLionel Sambuc
1456f4a2713aSLionel Sambuc switch (Triple.getOS()) {
1457f4a2713aSLionel Sambuc case llvm::Triple::FreeBSD:
1458f4a2713aSLionel Sambuc case llvm::Triple::NetBSD:
1459f4a2713aSLionel Sambuc case llvm::Triple::OpenBSD:
1460f4a2713aSLionel Sambuc return "i486";
1461f4a2713aSLionel Sambuc case llvm::Triple::Haiku:
14624684ddb6SLionel Sambuc case llvm::Triple::Minix:
1463f4a2713aSLionel Sambuc return "i586";
1464f4a2713aSLionel Sambuc case llvm::Triple::Bitrig:
1465f4a2713aSLionel Sambuc return "i686";
1466f4a2713aSLionel Sambuc default:
1467f4a2713aSLionel Sambuc // Fallback to p4.
1468f4a2713aSLionel Sambuc return "pentium4";
1469f4a2713aSLionel Sambuc }
1470f4a2713aSLionel Sambuc }
1471f4a2713aSLionel Sambuc
getCPUName(const ArgList & Args,const llvm::Triple & T)1472f4a2713aSLionel Sambuc static std::string getCPUName(const ArgList &Args, const llvm::Triple &T) {
1473f4a2713aSLionel Sambuc switch(T.getArch()) {
1474f4a2713aSLionel Sambuc default:
1475f4a2713aSLionel Sambuc return "";
1476f4a2713aSLionel Sambuc
1477f4a2713aSLionel Sambuc case llvm::Triple::aarch64:
1478*0a6a1f1dSLionel Sambuc case llvm::Triple::aarch64_be:
1479*0a6a1f1dSLionel Sambuc return getAArch64TargetCPU(Args);
1480f4a2713aSLionel Sambuc
1481f4a2713aSLionel Sambuc case llvm::Triple::arm:
1482*0a6a1f1dSLionel Sambuc case llvm::Triple::armeb:
1483f4a2713aSLionel Sambuc case llvm::Triple::thumb:
1484*0a6a1f1dSLionel Sambuc case llvm::Triple::thumbeb:
1485*0a6a1f1dSLionel Sambuc return arm::getARMTargetCPU(Args, T);
1486f4a2713aSLionel Sambuc
1487f4a2713aSLionel Sambuc case llvm::Triple::mips:
1488f4a2713aSLionel Sambuc case llvm::Triple::mipsel:
1489f4a2713aSLionel Sambuc case llvm::Triple::mips64:
1490f4a2713aSLionel Sambuc case llvm::Triple::mips64el: {
1491f4a2713aSLionel Sambuc StringRef CPUName;
1492f4a2713aSLionel Sambuc StringRef ABIName;
1493*0a6a1f1dSLionel Sambuc mips::getMipsCPUAndABI(Args, T, CPUName, ABIName);
1494f4a2713aSLionel Sambuc return CPUName;
1495f4a2713aSLionel Sambuc }
1496f4a2713aSLionel Sambuc
1497f4a2713aSLionel Sambuc case llvm::Triple::ppc:
1498f4a2713aSLionel Sambuc case llvm::Triple::ppc64:
1499f4a2713aSLionel Sambuc case llvm::Triple::ppc64le: {
1500f4a2713aSLionel Sambuc std::string TargetCPUName = getPPCTargetCPU(Args);
1501f4a2713aSLionel Sambuc // LLVM may default to generating code for the native CPU,
1502f4a2713aSLionel Sambuc // but, like gcc, we default to a more generic option for
1503f4a2713aSLionel Sambuc // each architecture. (except on Darwin)
1504f4a2713aSLionel Sambuc if (TargetCPUName.empty() && !T.isOSDarwin()) {
1505f4a2713aSLionel Sambuc if (T.getArch() == llvm::Triple::ppc64)
1506f4a2713aSLionel Sambuc TargetCPUName = "ppc64";
1507f4a2713aSLionel Sambuc else if (T.getArch() == llvm::Triple::ppc64le)
1508f4a2713aSLionel Sambuc TargetCPUName = "ppc64le";
1509f4a2713aSLionel Sambuc else
1510f4a2713aSLionel Sambuc TargetCPUName = "ppc";
1511f4a2713aSLionel Sambuc }
1512f4a2713aSLionel Sambuc return TargetCPUName;
1513f4a2713aSLionel Sambuc }
1514f4a2713aSLionel Sambuc
1515f4a2713aSLionel Sambuc case llvm::Triple::sparc:
1516*0a6a1f1dSLionel Sambuc case llvm::Triple::sparcv9:
1517*0a6a1f1dSLionel Sambuc if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
1518f4a2713aSLionel Sambuc return A->getValue();
1519f4a2713aSLionel Sambuc return "";
1520f4a2713aSLionel Sambuc
1521f4a2713aSLionel Sambuc case llvm::Triple::x86:
1522f4a2713aSLionel Sambuc case llvm::Triple::x86_64:
1523f4a2713aSLionel Sambuc return getX86TargetCPU(Args, T);
1524f4a2713aSLionel Sambuc
1525f4a2713aSLionel Sambuc case llvm::Triple::hexagon:
1526f4a2713aSLionel Sambuc return "hexagon" + toolchains::Hexagon_TC::GetTargetCPU(Args).str();
1527f4a2713aSLionel Sambuc
1528f4a2713aSLionel Sambuc case llvm::Triple::systemz:
1529f4a2713aSLionel Sambuc return getSystemZTargetCPU(Args);
1530f4a2713aSLionel Sambuc
1531f4a2713aSLionel Sambuc case llvm::Triple::r600:
1532*0a6a1f1dSLionel Sambuc case llvm::Triple::amdgcn:
1533f4a2713aSLionel Sambuc return getR600TargetGPU(Args);
1534f4a2713aSLionel Sambuc }
1535f4a2713aSLionel Sambuc }
1536f4a2713aSLionel Sambuc
AddGoldPlugin(const ToolChain & ToolChain,const ArgList & Args,ArgStringList & CmdArgs)1537*0a6a1f1dSLionel Sambuc static void AddGoldPlugin(const ToolChain &ToolChain, const ArgList &Args,
1538*0a6a1f1dSLionel Sambuc ArgStringList &CmdArgs) {
1539*0a6a1f1dSLionel Sambuc // Tell the linker to load the plugin. This has to come before AddLinkerInputs
1540*0a6a1f1dSLionel Sambuc // as gold requires -plugin to come before any -plugin-opt that -Wl might
1541*0a6a1f1dSLionel Sambuc // forward.
1542*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-plugin");
1543*0a6a1f1dSLionel Sambuc std::string Plugin = ToolChain.getDriver().Dir + "/../lib" CLANG_LIBDIR_SUFFIX "/LLVMgold.so";
1544*0a6a1f1dSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(Plugin));
1545*0a6a1f1dSLionel Sambuc
1546*0a6a1f1dSLionel Sambuc // Try to pass driver level flags relevant to LTO code generation down to
1547*0a6a1f1dSLionel Sambuc // the plugin.
1548*0a6a1f1dSLionel Sambuc
1549*0a6a1f1dSLionel Sambuc // Handle flags for selecting CPU variants.
1550*0a6a1f1dSLionel Sambuc std::string CPU = getCPUName(Args, ToolChain.getTriple());
1551*0a6a1f1dSLionel Sambuc if (!CPU.empty())
1552*0a6a1f1dSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(Twine("-plugin-opt=mcpu=") + CPU));
1553*0a6a1f1dSLionel Sambuc }
1554*0a6a1f1dSLionel Sambuc
getX86TargetFeatures(const Driver & D,const llvm::Triple & Triple,const ArgList & Args,std::vector<const char * > & Features)1555*0a6a1f1dSLionel Sambuc static void getX86TargetFeatures(const Driver & D,
1556*0a6a1f1dSLionel Sambuc const llvm::Triple &Triple,
1557f4a2713aSLionel Sambuc const ArgList &Args,
1558f4a2713aSLionel Sambuc std::vector<const char *> &Features) {
1559f4a2713aSLionel Sambuc if (Triple.getArchName() == "x86_64h") {
1560f4a2713aSLionel Sambuc // x86_64h implies quite a few of the more modern subtarget features
1561f4a2713aSLionel Sambuc // for Haswell class CPUs, but not all of them. Opt-out of a few.
1562f4a2713aSLionel Sambuc Features.push_back("-rdrnd");
1563f4a2713aSLionel Sambuc Features.push_back("-aes");
1564f4a2713aSLionel Sambuc Features.push_back("-pclmul");
1565f4a2713aSLionel Sambuc Features.push_back("-rtm");
1566f4a2713aSLionel Sambuc Features.push_back("-hle");
1567f4a2713aSLionel Sambuc Features.push_back("-fsgsbase");
1568f4a2713aSLionel Sambuc }
1569f4a2713aSLionel Sambuc
1570*0a6a1f1dSLionel Sambuc // Add features to comply with gcc on Android
1571*0a6a1f1dSLionel Sambuc if (Triple.getEnvironment() == llvm::Triple::Android) {
1572*0a6a1f1dSLionel Sambuc if (Triple.getArch() == llvm::Triple::x86_64) {
1573*0a6a1f1dSLionel Sambuc Features.push_back("+sse4.2");
1574*0a6a1f1dSLionel Sambuc Features.push_back("+popcnt");
1575*0a6a1f1dSLionel Sambuc } else
1576*0a6a1f1dSLionel Sambuc Features.push_back("+ssse3");
1577*0a6a1f1dSLionel Sambuc }
1578*0a6a1f1dSLionel Sambuc
1579*0a6a1f1dSLionel Sambuc // Set features according to the -arch flag on MSVC
1580*0a6a1f1dSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT__SLASH_arch)) {
1581*0a6a1f1dSLionel Sambuc StringRef Arch = A->getValue();
1582*0a6a1f1dSLionel Sambuc bool ArchUsed = false;
1583*0a6a1f1dSLionel Sambuc // First, look for flags that are shared in x86 and x86-64.
1584*0a6a1f1dSLionel Sambuc if (Triple.getArch() == llvm::Triple::x86_64 ||
1585*0a6a1f1dSLionel Sambuc Triple.getArch() == llvm::Triple::x86) {
1586*0a6a1f1dSLionel Sambuc if (Arch == "AVX" || Arch == "AVX2") {
1587*0a6a1f1dSLionel Sambuc ArchUsed = true;
1588*0a6a1f1dSLionel Sambuc Features.push_back(Args.MakeArgString("+" + Arch.lower()));
1589*0a6a1f1dSLionel Sambuc }
1590*0a6a1f1dSLionel Sambuc }
1591*0a6a1f1dSLionel Sambuc // Then, look for x86-specific flags.
1592*0a6a1f1dSLionel Sambuc if (Triple.getArch() == llvm::Triple::x86) {
1593*0a6a1f1dSLionel Sambuc if (Arch == "IA32") {
1594*0a6a1f1dSLionel Sambuc ArchUsed = true;
1595*0a6a1f1dSLionel Sambuc } else if (Arch == "SSE" || Arch == "SSE2") {
1596*0a6a1f1dSLionel Sambuc ArchUsed = true;
1597*0a6a1f1dSLionel Sambuc Features.push_back(Args.MakeArgString("+" + Arch.lower()));
1598*0a6a1f1dSLionel Sambuc }
1599*0a6a1f1dSLionel Sambuc }
1600*0a6a1f1dSLionel Sambuc if (!ArchUsed)
1601*0a6a1f1dSLionel Sambuc D.Diag(clang::diag::warn_drv_unused_argument) << A->getAsString(Args);
1602*0a6a1f1dSLionel Sambuc }
1603*0a6a1f1dSLionel Sambuc
1604f4a2713aSLionel Sambuc // Now add any that the user explicitly requested on the command line,
1605f4a2713aSLionel Sambuc // which may override the defaults.
1606f4a2713aSLionel Sambuc for (arg_iterator it = Args.filtered_begin(options::OPT_m_x86_Features_Group),
1607f4a2713aSLionel Sambuc ie = Args.filtered_end();
1608f4a2713aSLionel Sambuc it != ie; ++it) {
1609f4a2713aSLionel Sambuc StringRef Name = (*it)->getOption().getName();
1610f4a2713aSLionel Sambuc (*it)->claim();
1611f4a2713aSLionel Sambuc
1612f4a2713aSLionel Sambuc // Skip over "-m".
1613f4a2713aSLionel Sambuc assert(Name.startswith("m") && "Invalid feature name.");
1614f4a2713aSLionel Sambuc Name = Name.substr(1);
1615f4a2713aSLionel Sambuc
1616f4a2713aSLionel Sambuc bool IsNegative = Name.startswith("no-");
1617f4a2713aSLionel Sambuc if (IsNegative)
1618f4a2713aSLionel Sambuc Name = Name.substr(3);
1619f4a2713aSLionel Sambuc
1620f4a2713aSLionel Sambuc Features.push_back(Args.MakeArgString((IsNegative ? "-" : "+") + Name));
1621f4a2713aSLionel Sambuc }
1622f4a2713aSLionel Sambuc }
1623f4a2713aSLionel Sambuc
AddX86TargetArgs(const ArgList & Args,ArgStringList & CmdArgs) const1624f4a2713aSLionel Sambuc void Clang::AddX86TargetArgs(const ArgList &Args,
1625f4a2713aSLionel Sambuc ArgStringList &CmdArgs) const {
1626f4a2713aSLionel Sambuc if (!Args.hasFlag(options::OPT_mred_zone,
1627f4a2713aSLionel Sambuc options::OPT_mno_red_zone,
1628f4a2713aSLionel Sambuc true) ||
1629f4a2713aSLionel Sambuc Args.hasArg(options::OPT_mkernel) ||
1630f4a2713aSLionel Sambuc Args.hasArg(options::OPT_fapple_kext))
1631f4a2713aSLionel Sambuc CmdArgs.push_back("-disable-red-zone");
1632f4a2713aSLionel Sambuc
1633f4a2713aSLionel Sambuc // Default to avoid implicit floating-point for kernel/kext code, but allow
1634f4a2713aSLionel Sambuc // that to be overridden with -mno-soft-float.
1635f4a2713aSLionel Sambuc bool NoImplicitFloat = (Args.hasArg(options::OPT_mkernel) ||
1636f4a2713aSLionel Sambuc Args.hasArg(options::OPT_fapple_kext));
1637f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_msoft_float,
1638f4a2713aSLionel Sambuc options::OPT_mno_soft_float,
1639f4a2713aSLionel Sambuc options::OPT_mimplicit_float,
1640f4a2713aSLionel Sambuc options::OPT_mno_implicit_float)) {
1641f4a2713aSLionel Sambuc const Option &O = A->getOption();
1642f4a2713aSLionel Sambuc NoImplicitFloat = (O.matches(options::OPT_mno_implicit_float) ||
1643f4a2713aSLionel Sambuc O.matches(options::OPT_msoft_float));
1644f4a2713aSLionel Sambuc }
1645f4a2713aSLionel Sambuc if (NoImplicitFloat)
1646f4a2713aSLionel Sambuc CmdArgs.push_back("-no-implicit-float");
1647*0a6a1f1dSLionel Sambuc
1648*0a6a1f1dSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_masm_EQ)) {
1649*0a6a1f1dSLionel Sambuc StringRef Value = A->getValue();
1650*0a6a1f1dSLionel Sambuc if (Value == "intel" || Value == "att") {
1651*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-mllvm");
1652*0a6a1f1dSLionel Sambuc CmdArgs.push_back(Args.MakeArgString("-x86-asm-syntax=" + Value));
1653*0a6a1f1dSLionel Sambuc } else {
1654*0a6a1f1dSLionel Sambuc getToolChain().getDriver().Diag(diag::err_drv_unsupported_option_argument)
1655*0a6a1f1dSLionel Sambuc << A->getOption().getName() << Value;
1656*0a6a1f1dSLionel Sambuc }
1657*0a6a1f1dSLionel Sambuc }
1658f4a2713aSLionel Sambuc }
1659f4a2713aSLionel Sambuc
HasPICArg(const ArgList & Args)1660f4a2713aSLionel Sambuc static inline bool HasPICArg(const ArgList &Args) {
1661f4a2713aSLionel Sambuc return Args.hasArg(options::OPT_fPIC)
1662f4a2713aSLionel Sambuc || Args.hasArg(options::OPT_fpic);
1663f4a2713aSLionel Sambuc }
1664f4a2713aSLionel Sambuc
GetLastSmallDataThresholdArg(const ArgList & Args)1665f4a2713aSLionel Sambuc static Arg *GetLastSmallDataThresholdArg(const ArgList &Args) {
1666f4a2713aSLionel Sambuc return Args.getLastArg(options::OPT_G,
1667f4a2713aSLionel Sambuc options::OPT_G_EQ,
1668f4a2713aSLionel Sambuc options::OPT_msmall_data_threshold_EQ);
1669f4a2713aSLionel Sambuc }
1670f4a2713aSLionel Sambuc
GetHexagonSmallDataThresholdValue(const ArgList & Args)1671f4a2713aSLionel Sambuc static std::string GetHexagonSmallDataThresholdValue(const ArgList &Args) {
1672f4a2713aSLionel Sambuc std::string value;
1673f4a2713aSLionel Sambuc if (HasPICArg(Args))
1674f4a2713aSLionel Sambuc value = "0";
1675f4a2713aSLionel Sambuc else if (Arg *A = GetLastSmallDataThresholdArg(Args)) {
1676f4a2713aSLionel Sambuc value = A->getValue();
1677f4a2713aSLionel Sambuc A->claim();
1678f4a2713aSLionel Sambuc }
1679f4a2713aSLionel Sambuc return value;
1680f4a2713aSLionel Sambuc }
1681f4a2713aSLionel Sambuc
AddHexagonTargetArgs(const ArgList & Args,ArgStringList & CmdArgs) const1682f4a2713aSLionel Sambuc void Clang::AddHexagonTargetArgs(const ArgList &Args,
1683f4a2713aSLionel Sambuc ArgStringList &CmdArgs) const {
1684f4a2713aSLionel Sambuc CmdArgs.push_back("-fno-signed-char");
1685f4a2713aSLionel Sambuc CmdArgs.push_back("-mqdsp6-compat");
1686f4a2713aSLionel Sambuc CmdArgs.push_back("-Wreturn-type");
1687f4a2713aSLionel Sambuc
1688f4a2713aSLionel Sambuc std::string SmallDataThreshold = GetHexagonSmallDataThresholdValue(Args);
1689f4a2713aSLionel Sambuc if (!SmallDataThreshold.empty()) {
1690f4a2713aSLionel Sambuc CmdArgs.push_back ("-mllvm");
1691f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(
1692f4a2713aSLionel Sambuc "-hexagon-small-data-threshold=" + SmallDataThreshold));
1693f4a2713aSLionel Sambuc }
1694f4a2713aSLionel Sambuc
1695f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_fno_short_enums))
1696f4a2713aSLionel Sambuc CmdArgs.push_back("-fshort-enums");
1697f4a2713aSLionel Sambuc if (Args.getLastArg(options::OPT_mieee_rnd_near)) {
1698f4a2713aSLionel Sambuc CmdArgs.push_back ("-mllvm");
1699f4a2713aSLionel Sambuc CmdArgs.push_back ("-enable-hexagon-ieee-rnd-near");
1700f4a2713aSLionel Sambuc }
1701f4a2713aSLionel Sambuc CmdArgs.push_back ("-mllvm");
1702f4a2713aSLionel Sambuc CmdArgs.push_back ("-machine-sink-split=0");
1703f4a2713aSLionel Sambuc }
1704f4a2713aSLionel Sambuc
1705*0a6a1f1dSLionel Sambuc // Decode AArch64 features from string like +[no]featureA+[no]featureB+...
DecodeAArch64Features(const Driver & D,StringRef text,std::vector<const char * > & Features)1706*0a6a1f1dSLionel Sambuc static bool DecodeAArch64Features(const Driver &D, StringRef text,
1707*0a6a1f1dSLionel Sambuc std::vector<const char *> &Features) {
1708*0a6a1f1dSLionel Sambuc SmallVector<StringRef, 8> Split;
1709*0a6a1f1dSLionel Sambuc text.split(Split, StringRef("+"), -1, false);
1710*0a6a1f1dSLionel Sambuc
1711*0a6a1f1dSLionel Sambuc for (unsigned I = 0, E = Split.size(); I != E; ++I) {
1712*0a6a1f1dSLionel Sambuc const char *result = llvm::StringSwitch<const char *>(Split[I])
1713*0a6a1f1dSLionel Sambuc .Case("fp", "+fp-armv8")
1714*0a6a1f1dSLionel Sambuc .Case("simd", "+neon")
1715*0a6a1f1dSLionel Sambuc .Case("crc", "+crc")
1716*0a6a1f1dSLionel Sambuc .Case("crypto", "+crypto")
1717*0a6a1f1dSLionel Sambuc .Case("nofp", "-fp-armv8")
1718*0a6a1f1dSLionel Sambuc .Case("nosimd", "-neon")
1719*0a6a1f1dSLionel Sambuc .Case("nocrc", "-crc")
1720*0a6a1f1dSLionel Sambuc .Case("nocrypto", "-crypto")
1721*0a6a1f1dSLionel Sambuc .Default(nullptr);
1722*0a6a1f1dSLionel Sambuc if (result)
1723*0a6a1f1dSLionel Sambuc Features.push_back(result);
1724*0a6a1f1dSLionel Sambuc else if (Split[I] == "neon" || Split[I] == "noneon")
1725*0a6a1f1dSLionel Sambuc D.Diag(diag::err_drv_no_neon_modifier);
1726*0a6a1f1dSLionel Sambuc else
1727*0a6a1f1dSLionel Sambuc return false;
1728*0a6a1f1dSLionel Sambuc }
1729*0a6a1f1dSLionel Sambuc return true;
1730*0a6a1f1dSLionel Sambuc }
1731*0a6a1f1dSLionel Sambuc
1732*0a6a1f1dSLionel Sambuc // Check if the CPU name and feature modifiers in -mcpu are legal. If yes,
1733*0a6a1f1dSLionel Sambuc // decode CPU and feature.
DecodeAArch64Mcpu(const Driver & D,StringRef Mcpu,StringRef & CPU,std::vector<const char * > & Features)1734*0a6a1f1dSLionel Sambuc static bool DecodeAArch64Mcpu(const Driver &D, StringRef Mcpu, StringRef &CPU,
1735*0a6a1f1dSLionel Sambuc std::vector<const char *> &Features) {
1736*0a6a1f1dSLionel Sambuc std::pair<StringRef, StringRef> Split = Mcpu.split("+");
1737*0a6a1f1dSLionel Sambuc CPU = Split.first;
1738*0a6a1f1dSLionel Sambuc if (CPU == "cyclone" || CPU == "cortex-a53" || CPU == "cortex-a57") {
1739*0a6a1f1dSLionel Sambuc Features.push_back("+neon");
1740*0a6a1f1dSLionel Sambuc Features.push_back("+crc");
1741*0a6a1f1dSLionel Sambuc Features.push_back("+crypto");
1742*0a6a1f1dSLionel Sambuc } else if (CPU == "generic") {
1743*0a6a1f1dSLionel Sambuc Features.push_back("+neon");
1744*0a6a1f1dSLionel Sambuc } else {
1745*0a6a1f1dSLionel Sambuc return false;
1746*0a6a1f1dSLionel Sambuc }
1747*0a6a1f1dSLionel Sambuc
1748*0a6a1f1dSLionel Sambuc if (Split.second.size() && !DecodeAArch64Features(D, Split.second, Features))
1749*0a6a1f1dSLionel Sambuc return false;
1750*0a6a1f1dSLionel Sambuc
1751*0a6a1f1dSLionel Sambuc return true;
1752*0a6a1f1dSLionel Sambuc }
1753*0a6a1f1dSLionel Sambuc
1754*0a6a1f1dSLionel Sambuc static bool
getAArch64ArchFeaturesFromMarch(const Driver & D,StringRef March,const ArgList & Args,std::vector<const char * > & Features)1755*0a6a1f1dSLionel Sambuc getAArch64ArchFeaturesFromMarch(const Driver &D, StringRef March,
1756*0a6a1f1dSLionel Sambuc const ArgList &Args,
1757*0a6a1f1dSLionel Sambuc std::vector<const char *> &Features) {
1758*0a6a1f1dSLionel Sambuc std::pair<StringRef, StringRef> Split = March.split("+");
1759*0a6a1f1dSLionel Sambuc if (Split.first != "armv8-a")
1760*0a6a1f1dSLionel Sambuc return false;
1761*0a6a1f1dSLionel Sambuc
1762*0a6a1f1dSLionel Sambuc if (Split.second.size() && !DecodeAArch64Features(D, Split.second, Features))
1763*0a6a1f1dSLionel Sambuc return false;
1764*0a6a1f1dSLionel Sambuc
1765*0a6a1f1dSLionel Sambuc return true;
1766*0a6a1f1dSLionel Sambuc }
1767*0a6a1f1dSLionel Sambuc
1768*0a6a1f1dSLionel Sambuc static bool
getAArch64ArchFeaturesFromMcpu(const Driver & D,StringRef Mcpu,const ArgList & Args,std::vector<const char * > & Features)1769*0a6a1f1dSLionel Sambuc getAArch64ArchFeaturesFromMcpu(const Driver &D, StringRef Mcpu,
1770*0a6a1f1dSLionel Sambuc const ArgList &Args,
1771*0a6a1f1dSLionel Sambuc std::vector<const char *> &Features) {
1772*0a6a1f1dSLionel Sambuc StringRef CPU;
1773*0a6a1f1dSLionel Sambuc if (!DecodeAArch64Mcpu(D, Mcpu, CPU, Features))
1774*0a6a1f1dSLionel Sambuc return false;
1775*0a6a1f1dSLionel Sambuc
1776*0a6a1f1dSLionel Sambuc return true;
1777*0a6a1f1dSLionel Sambuc }
1778*0a6a1f1dSLionel Sambuc
1779*0a6a1f1dSLionel Sambuc static bool
getAArch64MicroArchFeaturesFromMtune(const Driver & D,StringRef Mtune,const ArgList & Args,std::vector<const char * > & Features)1780*0a6a1f1dSLionel Sambuc getAArch64MicroArchFeaturesFromMtune(const Driver &D, StringRef Mtune,
1781*0a6a1f1dSLionel Sambuc const ArgList &Args,
1782*0a6a1f1dSLionel Sambuc std::vector<const char *> &Features) {
1783*0a6a1f1dSLionel Sambuc // Handle CPU name is 'native'.
1784*0a6a1f1dSLionel Sambuc if (Mtune == "native")
1785*0a6a1f1dSLionel Sambuc Mtune = llvm::sys::getHostCPUName();
1786*0a6a1f1dSLionel Sambuc if (Mtune == "cyclone") {
1787*0a6a1f1dSLionel Sambuc Features.push_back("+zcm");
1788*0a6a1f1dSLionel Sambuc Features.push_back("+zcz");
1789*0a6a1f1dSLionel Sambuc }
1790*0a6a1f1dSLionel Sambuc return true;
1791*0a6a1f1dSLionel Sambuc }
1792*0a6a1f1dSLionel Sambuc
1793*0a6a1f1dSLionel Sambuc static bool
getAArch64MicroArchFeaturesFromMcpu(const Driver & D,StringRef Mcpu,const ArgList & Args,std::vector<const char * > & Features)1794*0a6a1f1dSLionel Sambuc getAArch64MicroArchFeaturesFromMcpu(const Driver &D, StringRef Mcpu,
1795*0a6a1f1dSLionel Sambuc const ArgList &Args,
1796*0a6a1f1dSLionel Sambuc std::vector<const char *> &Features) {
1797*0a6a1f1dSLionel Sambuc StringRef CPU;
1798*0a6a1f1dSLionel Sambuc std::vector<const char *> DecodedFeature;
1799*0a6a1f1dSLionel Sambuc if (!DecodeAArch64Mcpu(D, Mcpu, CPU, DecodedFeature))
1800*0a6a1f1dSLionel Sambuc return false;
1801*0a6a1f1dSLionel Sambuc
1802*0a6a1f1dSLionel Sambuc return getAArch64MicroArchFeaturesFromMtune(D, CPU, Args, Features);
1803*0a6a1f1dSLionel Sambuc }
1804*0a6a1f1dSLionel Sambuc
getAArch64TargetFeatures(const Driver & D,const ArgList & Args,std::vector<const char * > & Features)1805f4a2713aSLionel Sambuc static void getAArch64TargetFeatures(const Driver &D, const ArgList &Args,
1806f4a2713aSLionel Sambuc std::vector<const char *> &Features) {
1807*0a6a1f1dSLionel Sambuc Arg *A;
1808*0a6a1f1dSLionel Sambuc bool success = true;
1809*0a6a1f1dSLionel Sambuc // Enable NEON by default.
1810*0a6a1f1dSLionel Sambuc Features.push_back("+neon");
1811*0a6a1f1dSLionel Sambuc if ((A = Args.getLastArg(options::OPT_march_EQ)))
1812*0a6a1f1dSLionel Sambuc success = getAArch64ArchFeaturesFromMarch(D, A->getValue(), Args, Features);
1813*0a6a1f1dSLionel Sambuc else if ((A = Args.getLastArg(options::OPT_mcpu_EQ)))
1814*0a6a1f1dSLionel Sambuc success = getAArch64ArchFeaturesFromMcpu(D, A->getValue(), Args, Features);
1815*0a6a1f1dSLionel Sambuc else if (Args.hasArg(options::OPT_arch))
1816*0a6a1f1dSLionel Sambuc success = getAArch64ArchFeaturesFromMcpu(D, getAArch64TargetCPU(Args), Args,
1817*0a6a1f1dSLionel Sambuc Features);
1818*0a6a1f1dSLionel Sambuc
1819*0a6a1f1dSLionel Sambuc if (success && (A = Args.getLastArg(options::OPT_mtune_EQ)))
1820*0a6a1f1dSLionel Sambuc success =
1821*0a6a1f1dSLionel Sambuc getAArch64MicroArchFeaturesFromMtune(D, A->getValue(), Args, Features);
1822*0a6a1f1dSLionel Sambuc else if (success && (A = Args.getLastArg(options::OPT_mcpu_EQ)))
1823*0a6a1f1dSLionel Sambuc success =
1824*0a6a1f1dSLionel Sambuc getAArch64MicroArchFeaturesFromMcpu(D, A->getValue(), Args, Features);
1825*0a6a1f1dSLionel Sambuc else if (Args.hasArg(options::OPT_arch))
1826*0a6a1f1dSLionel Sambuc success = getAArch64MicroArchFeaturesFromMcpu(D, getAArch64TargetCPU(Args),
1827*0a6a1f1dSLionel Sambuc Args, Features);
1828*0a6a1f1dSLionel Sambuc
1829*0a6a1f1dSLionel Sambuc if (!success)
1830*0a6a1f1dSLionel Sambuc D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
1831*0a6a1f1dSLionel Sambuc
1832*0a6a1f1dSLionel Sambuc if (Args.getLastArg(options::OPT_mgeneral_regs_only)) {
1833*0a6a1f1dSLionel Sambuc Features.push_back("-fp-armv8");
1834*0a6a1f1dSLionel Sambuc Features.push_back("-crypto");
1835*0a6a1f1dSLionel Sambuc Features.push_back("-neon");
1836*0a6a1f1dSLionel Sambuc }
1837*0a6a1f1dSLionel Sambuc
1838*0a6a1f1dSLionel Sambuc // En/disable crc
1839*0a6a1f1dSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_mcrc,
1840*0a6a1f1dSLionel Sambuc options::OPT_mnocrc)) {
1841*0a6a1f1dSLionel Sambuc if (A->getOption().matches(options::OPT_mcrc))
1842*0a6a1f1dSLionel Sambuc Features.push_back("+crc");
1843*0a6a1f1dSLionel Sambuc else
1844*0a6a1f1dSLionel Sambuc Features.push_back("-crc");
1845*0a6a1f1dSLionel Sambuc }
1846f4a2713aSLionel Sambuc }
1847f4a2713aSLionel Sambuc
getTargetFeatures(const Driver & D,const llvm::Triple & Triple,const ArgList & Args,ArgStringList & CmdArgs,bool ForAS)1848f4a2713aSLionel Sambuc static void getTargetFeatures(const Driver &D, const llvm::Triple &Triple,
1849*0a6a1f1dSLionel Sambuc const ArgList &Args, ArgStringList &CmdArgs,
1850*0a6a1f1dSLionel Sambuc bool ForAS) {
1851f4a2713aSLionel Sambuc std::vector<const char *> Features;
1852f4a2713aSLionel Sambuc switch (Triple.getArch()) {
1853f4a2713aSLionel Sambuc default:
1854f4a2713aSLionel Sambuc break;
1855f4a2713aSLionel Sambuc case llvm::Triple::mips:
1856f4a2713aSLionel Sambuc case llvm::Triple::mipsel:
1857f4a2713aSLionel Sambuc case llvm::Triple::mips64:
1858f4a2713aSLionel Sambuc case llvm::Triple::mips64el:
1859*0a6a1f1dSLionel Sambuc getMIPSTargetFeatures(D, Triple, Args, Features);
1860f4a2713aSLionel Sambuc break;
1861f4a2713aSLionel Sambuc
1862f4a2713aSLionel Sambuc case llvm::Triple::arm:
1863*0a6a1f1dSLionel Sambuc case llvm::Triple::armeb:
1864f4a2713aSLionel Sambuc case llvm::Triple::thumb:
1865*0a6a1f1dSLionel Sambuc case llvm::Triple::thumbeb:
1866*0a6a1f1dSLionel Sambuc getARMTargetFeatures(D, Triple, Args, Features, ForAS);
1867f4a2713aSLionel Sambuc break;
1868f4a2713aSLionel Sambuc
1869f4a2713aSLionel Sambuc case llvm::Triple::ppc:
1870f4a2713aSLionel Sambuc case llvm::Triple::ppc64:
1871f4a2713aSLionel Sambuc case llvm::Triple::ppc64le:
1872f4a2713aSLionel Sambuc getPPCTargetFeatures(Args, Features);
1873f4a2713aSLionel Sambuc break;
1874f4a2713aSLionel Sambuc case llvm::Triple::sparc:
1875*0a6a1f1dSLionel Sambuc case llvm::Triple::sparcv9:
1876f4a2713aSLionel Sambuc getSparcTargetFeatures(Args, Features);
1877f4a2713aSLionel Sambuc break;
1878f4a2713aSLionel Sambuc case llvm::Triple::aarch64:
1879*0a6a1f1dSLionel Sambuc case llvm::Triple::aarch64_be:
1880f4a2713aSLionel Sambuc getAArch64TargetFeatures(D, Args, Features);
1881f4a2713aSLionel Sambuc break;
1882f4a2713aSLionel Sambuc case llvm::Triple::x86:
1883f4a2713aSLionel Sambuc case llvm::Triple::x86_64:
1884*0a6a1f1dSLionel Sambuc getX86TargetFeatures(D, Triple, Args, Features);
1885f4a2713aSLionel Sambuc break;
1886f4a2713aSLionel Sambuc }
1887f4a2713aSLionel Sambuc
1888f4a2713aSLionel Sambuc // Find the last of each feature.
1889f4a2713aSLionel Sambuc llvm::StringMap<unsigned> LastOpt;
1890f4a2713aSLionel Sambuc for (unsigned I = 0, N = Features.size(); I < N; ++I) {
1891f4a2713aSLionel Sambuc const char *Name = Features[I];
1892f4a2713aSLionel Sambuc assert(Name[0] == '-' || Name[0] == '+');
1893f4a2713aSLionel Sambuc LastOpt[Name + 1] = I;
1894f4a2713aSLionel Sambuc }
1895f4a2713aSLionel Sambuc
1896f4a2713aSLionel Sambuc for (unsigned I = 0, N = Features.size(); I < N; ++I) {
1897f4a2713aSLionel Sambuc // If this feature was overridden, ignore it.
1898f4a2713aSLionel Sambuc const char *Name = Features[I];
1899f4a2713aSLionel Sambuc llvm::StringMap<unsigned>::iterator LastI = LastOpt.find(Name + 1);
1900f4a2713aSLionel Sambuc assert(LastI != LastOpt.end());
1901f4a2713aSLionel Sambuc unsigned Last = LastI->second;
1902f4a2713aSLionel Sambuc if (Last != I)
1903f4a2713aSLionel Sambuc continue;
1904f4a2713aSLionel Sambuc
1905f4a2713aSLionel Sambuc CmdArgs.push_back("-target-feature");
1906f4a2713aSLionel Sambuc CmdArgs.push_back(Name);
1907f4a2713aSLionel Sambuc }
1908f4a2713aSLionel Sambuc }
1909f4a2713aSLionel Sambuc
1910f4a2713aSLionel Sambuc static bool
shouldUseExceptionTablesForObjCExceptions(const ObjCRuntime & runtime,const llvm::Triple & Triple)1911f4a2713aSLionel Sambuc shouldUseExceptionTablesForObjCExceptions(const ObjCRuntime &runtime,
1912f4a2713aSLionel Sambuc const llvm::Triple &Triple) {
1913f4a2713aSLionel Sambuc // We use the zero-cost exception tables for Objective-C if the non-fragile
1914f4a2713aSLionel Sambuc // ABI is enabled or when compiling for x86_64 and ARM on Snow Leopard and
1915f4a2713aSLionel Sambuc // later.
1916f4a2713aSLionel Sambuc if (runtime.isNonFragile())
1917f4a2713aSLionel Sambuc return true;
1918f4a2713aSLionel Sambuc
1919*0a6a1f1dSLionel Sambuc if (!Triple.isMacOSX())
1920f4a2713aSLionel Sambuc return false;
1921f4a2713aSLionel Sambuc
1922f4a2713aSLionel Sambuc return (!Triple.isMacOSXVersionLT(10,5) &&
1923f4a2713aSLionel Sambuc (Triple.getArch() == llvm::Triple::x86_64 ||
1924f4a2713aSLionel Sambuc Triple.getArch() == llvm::Triple::arm));
1925f4a2713aSLionel Sambuc }
1926f4a2713aSLionel Sambuc
1927*0a6a1f1dSLionel Sambuc // exceptionSettings() exists to share the logic between -cc1 and linker
1928*0a6a1f1dSLionel Sambuc // invocations.
exceptionSettings(const ArgList & Args,const llvm::Triple & Triple)1929*0a6a1f1dSLionel Sambuc static bool exceptionSettings(const ArgList &Args, const llvm::Triple &Triple) {
1930*0a6a1f1dSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_fexceptions,
1931*0a6a1f1dSLionel Sambuc options::OPT_fno_exceptions))
1932*0a6a1f1dSLionel Sambuc if (A->getOption().matches(options::OPT_fexceptions))
1933*0a6a1f1dSLionel Sambuc return true;
1934*0a6a1f1dSLionel Sambuc
1935*0a6a1f1dSLionel Sambuc return false;
1936*0a6a1f1dSLionel Sambuc }
1937*0a6a1f1dSLionel Sambuc
1938f4a2713aSLionel Sambuc /// addExceptionArgs - Adds exception related arguments to the driver command
1939f4a2713aSLionel Sambuc /// arguments. There's a master flag, -fexceptions and also language specific
1940f4a2713aSLionel Sambuc /// flags to enable/disable C++ and Objective-C exceptions.
1941f4a2713aSLionel Sambuc /// This makes it possible to for example disable C++ exceptions but enable
1942f4a2713aSLionel Sambuc /// Objective-C exceptions.
addExceptionArgs(const ArgList & Args,types::ID InputType,const llvm::Triple & Triple,bool KernelOrKext,const ObjCRuntime & objcRuntime,ArgStringList & CmdArgs)1943f4a2713aSLionel Sambuc static void addExceptionArgs(const ArgList &Args, types::ID InputType,
1944f4a2713aSLionel Sambuc const llvm::Triple &Triple,
1945f4a2713aSLionel Sambuc bool KernelOrKext,
1946f4a2713aSLionel Sambuc const ObjCRuntime &objcRuntime,
1947f4a2713aSLionel Sambuc ArgStringList &CmdArgs) {
1948f4a2713aSLionel Sambuc if (KernelOrKext) {
1949f4a2713aSLionel Sambuc // -mkernel and -fapple-kext imply no exceptions, so claim exception related
1950f4a2713aSLionel Sambuc // arguments now to avoid warnings about unused arguments.
1951f4a2713aSLionel Sambuc Args.ClaimAllArgs(options::OPT_fexceptions);
1952f4a2713aSLionel Sambuc Args.ClaimAllArgs(options::OPT_fno_exceptions);
1953f4a2713aSLionel Sambuc Args.ClaimAllArgs(options::OPT_fobjc_exceptions);
1954f4a2713aSLionel Sambuc Args.ClaimAllArgs(options::OPT_fno_objc_exceptions);
1955f4a2713aSLionel Sambuc Args.ClaimAllArgs(options::OPT_fcxx_exceptions);
1956f4a2713aSLionel Sambuc Args.ClaimAllArgs(options::OPT_fno_cxx_exceptions);
1957f4a2713aSLionel Sambuc return;
1958f4a2713aSLionel Sambuc }
1959f4a2713aSLionel Sambuc
1960*0a6a1f1dSLionel Sambuc // Gather the exception settings from the command line arguments.
1961*0a6a1f1dSLionel Sambuc bool EH = exceptionSettings(Args, Triple);
1962f4a2713aSLionel Sambuc
1963f4a2713aSLionel Sambuc // Obj-C exceptions are enabled by default, regardless of -fexceptions. This
1964f4a2713aSLionel Sambuc // is not necessarily sensible, but follows GCC.
1965f4a2713aSLionel Sambuc if (types::isObjC(InputType) &&
1966f4a2713aSLionel Sambuc Args.hasFlag(options::OPT_fobjc_exceptions,
1967f4a2713aSLionel Sambuc options::OPT_fno_objc_exceptions,
1968f4a2713aSLionel Sambuc true)) {
1969f4a2713aSLionel Sambuc CmdArgs.push_back("-fobjc-exceptions");
1970f4a2713aSLionel Sambuc
1971*0a6a1f1dSLionel Sambuc EH |= shouldUseExceptionTablesForObjCExceptions(objcRuntime, Triple);
1972f4a2713aSLionel Sambuc }
1973f4a2713aSLionel Sambuc
1974f4a2713aSLionel Sambuc if (types::isCXX(InputType)) {
1975*0a6a1f1dSLionel Sambuc bool CXXExceptionsEnabled = Triple.getArch() != llvm::Triple::xcore;
1976f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_fcxx_exceptions,
1977f4a2713aSLionel Sambuc options::OPT_fno_cxx_exceptions,
1978f4a2713aSLionel Sambuc options::OPT_fexceptions,
1979*0a6a1f1dSLionel Sambuc options::OPT_fno_exceptions))
1980*0a6a1f1dSLionel Sambuc CXXExceptionsEnabled =
1981*0a6a1f1dSLionel Sambuc A->getOption().matches(options::OPT_fcxx_exceptions) ||
1982*0a6a1f1dSLionel Sambuc A->getOption().matches(options::OPT_fexceptions);
1983f4a2713aSLionel Sambuc
1984f4a2713aSLionel Sambuc if (CXXExceptionsEnabled) {
1985f4a2713aSLionel Sambuc CmdArgs.push_back("-fcxx-exceptions");
1986f4a2713aSLionel Sambuc
1987*0a6a1f1dSLionel Sambuc EH = true;
1988f4a2713aSLionel Sambuc }
1989f4a2713aSLionel Sambuc }
1990f4a2713aSLionel Sambuc
1991*0a6a1f1dSLionel Sambuc if (EH)
1992f4a2713aSLionel Sambuc CmdArgs.push_back("-fexceptions");
1993f4a2713aSLionel Sambuc }
1994f4a2713aSLionel Sambuc
ShouldDisableAutolink(const ArgList & Args,const ToolChain & TC)1995f4a2713aSLionel Sambuc static bool ShouldDisableAutolink(const ArgList &Args,
1996f4a2713aSLionel Sambuc const ToolChain &TC) {
1997f4a2713aSLionel Sambuc bool Default = true;
1998f4a2713aSLionel Sambuc if (TC.getTriple().isOSDarwin()) {
1999f4a2713aSLionel Sambuc // The native darwin assembler doesn't support the linker_option directives,
2000f4a2713aSLionel Sambuc // so we disable them if we think the .s file will be passed to it.
2001f4a2713aSLionel Sambuc Default = TC.useIntegratedAs();
2002f4a2713aSLionel Sambuc }
2003f4a2713aSLionel Sambuc return !Args.hasFlag(options::OPT_fautolink, options::OPT_fno_autolink,
2004f4a2713aSLionel Sambuc Default);
2005f4a2713aSLionel Sambuc }
2006f4a2713aSLionel Sambuc
ShouldDisableDwarfDirectory(const ArgList & Args,const ToolChain & TC)2007f4a2713aSLionel Sambuc static bool ShouldDisableDwarfDirectory(const ArgList &Args,
2008f4a2713aSLionel Sambuc const ToolChain &TC) {
2009f4a2713aSLionel Sambuc bool UseDwarfDirectory = Args.hasFlag(options::OPT_fdwarf_directory_asm,
2010f4a2713aSLionel Sambuc options::OPT_fno_dwarf_directory_asm,
2011f4a2713aSLionel Sambuc TC.useIntegratedAs());
2012f4a2713aSLionel Sambuc return !UseDwarfDirectory;
2013f4a2713aSLionel Sambuc }
2014f4a2713aSLionel Sambuc
2015f4a2713aSLionel Sambuc /// \brief Check whether the given input tree contains any compilation actions.
ContainsCompileAction(const Action * A)2016f4a2713aSLionel Sambuc static bool ContainsCompileAction(const Action *A) {
2017*0a6a1f1dSLionel Sambuc if (isa<CompileJobAction>(A) || isa<BackendJobAction>(A))
2018f4a2713aSLionel Sambuc return true;
2019f4a2713aSLionel Sambuc
2020*0a6a1f1dSLionel Sambuc for (const auto &Act : *A)
2021*0a6a1f1dSLionel Sambuc if (ContainsCompileAction(Act))
2022f4a2713aSLionel Sambuc return true;
2023f4a2713aSLionel Sambuc
2024f4a2713aSLionel Sambuc return false;
2025f4a2713aSLionel Sambuc }
2026f4a2713aSLionel Sambuc
2027f4a2713aSLionel Sambuc /// \brief Check if -relax-all should be passed to the internal assembler.
2028f4a2713aSLionel Sambuc /// This is done by default when compiling non-assembler source with -O0.
UseRelaxAll(Compilation & C,const ArgList & Args)2029f4a2713aSLionel Sambuc static bool UseRelaxAll(Compilation &C, const ArgList &Args) {
2030f4a2713aSLionel Sambuc bool RelaxDefault = true;
2031f4a2713aSLionel Sambuc
2032f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_O_Group))
2033f4a2713aSLionel Sambuc RelaxDefault = A->getOption().matches(options::OPT_O0);
2034f4a2713aSLionel Sambuc
2035f4a2713aSLionel Sambuc if (RelaxDefault) {
2036f4a2713aSLionel Sambuc RelaxDefault = false;
2037*0a6a1f1dSLionel Sambuc for (const auto &Act : C.getActions()) {
2038*0a6a1f1dSLionel Sambuc if (ContainsCompileAction(Act)) {
2039f4a2713aSLionel Sambuc RelaxDefault = true;
2040f4a2713aSLionel Sambuc break;
2041f4a2713aSLionel Sambuc }
2042f4a2713aSLionel Sambuc }
2043f4a2713aSLionel Sambuc }
2044f4a2713aSLionel Sambuc
2045f4a2713aSLionel Sambuc return Args.hasFlag(options::OPT_mrelax_all, options::OPT_mno_relax_all,
2046f4a2713aSLionel Sambuc RelaxDefault);
2047f4a2713aSLionel Sambuc }
2048f4a2713aSLionel Sambuc
CollectArgsForIntegratedAssembler(Compilation & C,const ArgList & Args,ArgStringList & CmdArgs,const Driver & D)2049f4a2713aSLionel Sambuc static void CollectArgsForIntegratedAssembler(Compilation &C,
2050f4a2713aSLionel Sambuc const ArgList &Args,
2051f4a2713aSLionel Sambuc ArgStringList &CmdArgs,
2052f4a2713aSLionel Sambuc const Driver &D) {
2053f4a2713aSLionel Sambuc if (UseRelaxAll(C, Args))
2054f4a2713aSLionel Sambuc CmdArgs.push_back("-mrelax-all");
2055f4a2713aSLionel Sambuc
2056f4a2713aSLionel Sambuc // When passing -I arguments to the assembler we sometimes need to
2057f4a2713aSLionel Sambuc // unconditionally take the next argument. For example, when parsing
2058f4a2713aSLionel Sambuc // '-Wa,-I -Wa,foo' we need to accept the -Wa,foo arg after seeing the
2059f4a2713aSLionel Sambuc // -Wa,-I arg and when parsing '-Wa,-I,foo' we need to accept the 'foo'
2060f4a2713aSLionel Sambuc // arg after parsing the '-I' arg.
2061f4a2713aSLionel Sambuc bool TakeNextArg = false;
2062f4a2713aSLionel Sambuc
2063f4a2713aSLionel Sambuc // When using an integrated assembler, translate -Wa, and -Xassembler
2064f4a2713aSLionel Sambuc // options.
2065*0a6a1f1dSLionel Sambuc bool CompressDebugSections = false;
2066f4a2713aSLionel Sambuc for (arg_iterator it = Args.filtered_begin(options::OPT_Wa_COMMA,
2067f4a2713aSLionel Sambuc options::OPT_Xassembler),
2068f4a2713aSLionel Sambuc ie = Args.filtered_end(); it != ie; ++it) {
2069f4a2713aSLionel Sambuc const Arg *A = *it;
2070f4a2713aSLionel Sambuc A->claim();
2071f4a2713aSLionel Sambuc
2072f4a2713aSLionel Sambuc for (unsigned i = 0, e = A->getNumValues(); i != e; ++i) {
2073f4a2713aSLionel Sambuc StringRef Value = A->getValue(i);
2074f4a2713aSLionel Sambuc if (TakeNextArg) {
2075f4a2713aSLionel Sambuc CmdArgs.push_back(Value.data());
2076f4a2713aSLionel Sambuc TakeNextArg = false;
2077f4a2713aSLionel Sambuc continue;
2078f4a2713aSLionel Sambuc }
2079f4a2713aSLionel Sambuc
2080f4a2713aSLionel Sambuc if (Value == "-force_cpusubtype_ALL") {
2081f4a2713aSLionel Sambuc // Do nothing, this is the default and we don't support anything else.
2082f4a2713aSLionel Sambuc } else if (Value == "-L") {
2083f4a2713aSLionel Sambuc CmdArgs.push_back("-msave-temp-labels");
2084f4a2713aSLionel Sambuc } else if (Value == "--fatal-warnings") {
2085*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-massembler-fatal-warnings");
2086f4a2713aSLionel Sambuc } else if (Value == "--noexecstack") {
2087f4a2713aSLionel Sambuc CmdArgs.push_back("-mnoexecstack");
2088*0a6a1f1dSLionel Sambuc } else if (Value == "-compress-debug-sections" ||
2089*0a6a1f1dSLionel Sambuc Value == "--compress-debug-sections") {
2090*0a6a1f1dSLionel Sambuc CompressDebugSections = true;
2091*0a6a1f1dSLionel Sambuc } else if (Value == "-nocompress-debug-sections" ||
2092*0a6a1f1dSLionel Sambuc Value == "--nocompress-debug-sections") {
2093*0a6a1f1dSLionel Sambuc CompressDebugSections = false;
2094f4a2713aSLionel Sambuc } else if (Value.startswith("-I")) {
2095f4a2713aSLionel Sambuc CmdArgs.push_back(Value.data());
2096f4a2713aSLionel Sambuc // We need to consume the next argument if the current arg is a plain
2097f4a2713aSLionel Sambuc // -I. The next arg will be the include directory.
2098f4a2713aSLionel Sambuc if (Value == "-I")
2099f4a2713aSLionel Sambuc TakeNextArg = true;
2100*0a6a1f1dSLionel Sambuc } else if (Value.startswith("-gdwarf-")) {
2101*0a6a1f1dSLionel Sambuc CmdArgs.push_back(Value.data());
2102f4a2713aSLionel Sambuc } else {
2103f4a2713aSLionel Sambuc D.Diag(diag::err_drv_unsupported_option_argument)
2104f4a2713aSLionel Sambuc << A->getOption().getName() << Value;
2105f4a2713aSLionel Sambuc }
2106f4a2713aSLionel Sambuc }
2107f4a2713aSLionel Sambuc }
2108*0a6a1f1dSLionel Sambuc if (CompressDebugSections) {
2109*0a6a1f1dSLionel Sambuc if (llvm::zlib::isAvailable())
2110*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-compress-debug-sections");
2111*0a6a1f1dSLionel Sambuc else
2112*0a6a1f1dSLionel Sambuc D.Diag(diag::warn_debug_compression_unavailable);
2113*0a6a1f1dSLionel Sambuc }
2114f4a2713aSLionel Sambuc }
2115f4a2713aSLionel Sambuc
2116*0a6a1f1dSLionel Sambuc // Until ARM libraries are build separately, we have them all in one library
getArchNameForCompilerRTLib(const ToolChain & TC)2117*0a6a1f1dSLionel Sambuc static StringRef getArchNameForCompilerRTLib(const ToolChain &TC) {
2118*0a6a1f1dSLionel Sambuc // FIXME: handle 64-bit
2119*0a6a1f1dSLionel Sambuc if (TC.getTriple().isOSWindows() &&
2120*0a6a1f1dSLionel Sambuc !TC.getTriple().isWindowsItaniumEnvironment())
2121*0a6a1f1dSLionel Sambuc return "i386";
2122*0a6a1f1dSLionel Sambuc if (TC.getArch() == llvm::Triple::arm || TC.getArch() == llvm::Triple::armeb)
2123*0a6a1f1dSLionel Sambuc return "arm";
2124*0a6a1f1dSLionel Sambuc return TC.getArchName();
2125*0a6a1f1dSLionel Sambuc }
2126*0a6a1f1dSLionel Sambuc
getCompilerRTLibDir(const ToolChain & TC)2127*0a6a1f1dSLionel Sambuc static SmallString<128> getCompilerRTLibDir(const ToolChain &TC) {
2128*0a6a1f1dSLionel Sambuc // The runtimes are located in the OS-specific resource directory.
2129*0a6a1f1dSLionel Sambuc SmallString<128> Res(TC.getDriver().ResourceDir);
2130*0a6a1f1dSLionel Sambuc const llvm::Triple &Triple = TC.getTriple();
2131*0a6a1f1dSLionel Sambuc // TC.getOS() yield "freebsd10.0" whereas "freebsd" is expected.
2132*0a6a1f1dSLionel Sambuc StringRef OSLibName =
2133*0a6a1f1dSLionel Sambuc (Triple.getOS() == llvm::Triple::FreeBSD) ? "freebsd" : TC.getOS();
2134*0a6a1f1dSLionel Sambuc llvm::sys::path::append(Res, "lib", OSLibName);
2135*0a6a1f1dSLionel Sambuc return Res;
2136*0a6a1f1dSLionel Sambuc }
2137*0a6a1f1dSLionel Sambuc
getCompilerRT(const ToolChain & TC,StringRef Component,bool Shared=false,const char * Env="")2138*0a6a1f1dSLionel Sambuc static SmallString<128> getCompilerRT(const ToolChain &TC, StringRef Component,
2139*0a6a1f1dSLionel Sambuc bool Shared = false,
2140*0a6a1f1dSLionel Sambuc const char *Env = "") {
2141*0a6a1f1dSLionel Sambuc bool IsOSWindows = TC.getTriple().isOSWindows();
2142*0a6a1f1dSLionel Sambuc StringRef Arch = getArchNameForCompilerRTLib(TC);
2143*0a6a1f1dSLionel Sambuc const char *Prefix = IsOSWindows ? "" : "lib";
2144*0a6a1f1dSLionel Sambuc const char *Suffix =
2145*0a6a1f1dSLionel Sambuc Shared ? (IsOSWindows ? ".dll" : ".so") : (IsOSWindows ? ".lib" : ".a");
2146*0a6a1f1dSLionel Sambuc
2147*0a6a1f1dSLionel Sambuc SmallString<128> Path = getCompilerRTLibDir(TC);
2148*0a6a1f1dSLionel Sambuc llvm::sys::path::append(Path, Prefix + Twine("clang_rt.") + Component + "-" +
2149*0a6a1f1dSLionel Sambuc Arch + Env + Suffix);
2150*0a6a1f1dSLionel Sambuc
2151*0a6a1f1dSLionel Sambuc return Path;
2152*0a6a1f1dSLionel Sambuc }
2153*0a6a1f1dSLionel Sambuc
2154*0a6a1f1dSLionel Sambuc // This adds the static libclang_rt.builtins-arch.a directly to the command line
2155*0a6a1f1dSLionel Sambuc // FIXME: Make sure we can also emit shared objects if they're requested
2156*0a6a1f1dSLionel Sambuc // and available, check for possible errors, etc.
addClangRT(const ToolChain & TC,const ArgList & Args,ArgStringList & CmdArgs)2157*0a6a1f1dSLionel Sambuc static void addClangRT(const ToolChain &TC, const ArgList &Args,
2158*0a6a1f1dSLionel Sambuc ArgStringList &CmdArgs) {
2159*0a6a1f1dSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(getCompilerRT(TC, "builtins")));
2160*0a6a1f1dSLionel Sambuc
2161*0a6a1f1dSLionel Sambuc if (!TC.getTriple().isOSWindows()) {
2162*0a6a1f1dSLionel Sambuc // FIXME: why do we link against gcc when we are using compiler-rt?
2163*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-lgcc_s");
2164*0a6a1f1dSLionel Sambuc if (TC.getDriver().CCCIsCXX())
2165*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-lgcc_eh");
2166*0a6a1f1dSLionel Sambuc }
2167*0a6a1f1dSLionel Sambuc }
2168*0a6a1f1dSLionel Sambuc
addProfileRT(const ToolChain & TC,const ArgList & Args,ArgStringList & CmdArgs)2169*0a6a1f1dSLionel Sambuc static void addProfileRT(const ToolChain &TC, const ArgList &Args,
2170*0a6a1f1dSLionel Sambuc ArgStringList &CmdArgs) {
2171*0a6a1f1dSLionel Sambuc if (!(Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs,
2172*0a6a1f1dSLionel Sambuc false) ||
2173f4a2713aSLionel Sambuc Args.hasArg(options::OPT_fprofile_generate) ||
2174*0a6a1f1dSLionel Sambuc Args.hasArg(options::OPT_fprofile_instr_generate) ||
2175f4a2713aSLionel Sambuc Args.hasArg(options::OPT_fcreate_profile) ||
2176f4a2713aSLionel Sambuc Args.hasArg(options::OPT_coverage)))
2177f4a2713aSLionel Sambuc return;
2178f4a2713aSLionel Sambuc
2179*0a6a1f1dSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(getCompilerRT(TC, "profile")));
2180f4a2713aSLionel Sambuc }
2181f4a2713aSLionel Sambuc
addSanitizerRuntime(const ToolChain & TC,const ArgList & Args,ArgStringList & CmdArgs,StringRef Sanitizer,bool IsShared)2182*0a6a1f1dSLionel Sambuc static void addSanitizerRuntime(const ToolChain &TC, const ArgList &Args,
2183*0a6a1f1dSLionel Sambuc ArgStringList &CmdArgs, StringRef Sanitizer,
2184*0a6a1f1dSLionel Sambuc bool IsShared) {
2185*0a6a1f1dSLionel Sambuc const char *Env = TC.getTriple().getEnvironment() == llvm::Triple::Android
2186*0a6a1f1dSLionel Sambuc ? "-android"
2187*0a6a1f1dSLionel Sambuc : "";
2188f4a2713aSLionel Sambuc
2189*0a6a1f1dSLionel Sambuc // Static runtimes must be forced into executable, so we wrap them in
2190f4a2713aSLionel Sambuc // whole-archive.
2191*0a6a1f1dSLionel Sambuc if (!IsShared)
2192*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-whole-archive");
2193*0a6a1f1dSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(getCompilerRT(TC, Sanitizer, IsShared,
2194*0a6a1f1dSLionel Sambuc Env)));
2195*0a6a1f1dSLionel Sambuc if (!IsShared)
2196*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-no-whole-archive");
2197*0a6a1f1dSLionel Sambuc }
2198f4a2713aSLionel Sambuc
2199*0a6a1f1dSLionel Sambuc // Tries to use a file with the list of dynamic symbols that need to be exported
2200*0a6a1f1dSLionel Sambuc // from the runtime library. Returns true if the file was found.
addSanitizerDynamicList(const ToolChain & TC,const ArgList & Args,ArgStringList & CmdArgs,StringRef Sanitizer)2201*0a6a1f1dSLionel Sambuc static bool addSanitizerDynamicList(const ToolChain &TC, const ArgList &Args,
2202*0a6a1f1dSLionel Sambuc ArgStringList &CmdArgs,
2203*0a6a1f1dSLionel Sambuc StringRef Sanitizer) {
2204*0a6a1f1dSLionel Sambuc SmallString<128> SanRT = getCompilerRT(TC, Sanitizer);
2205*0a6a1f1dSLionel Sambuc if (llvm::sys::fs::exists(SanRT + ".syms")) {
2206*0a6a1f1dSLionel Sambuc CmdArgs.push_back(Args.MakeArgString("--dynamic-list=" + SanRT + ".syms"));
2207*0a6a1f1dSLionel Sambuc return true;
2208*0a6a1f1dSLionel Sambuc }
2209*0a6a1f1dSLionel Sambuc return false;
2210*0a6a1f1dSLionel Sambuc }
2211f4a2713aSLionel Sambuc
linkSanitizerRuntimeDeps(const ToolChain & TC,ArgStringList & CmdArgs)2212*0a6a1f1dSLionel Sambuc static void linkSanitizerRuntimeDeps(const ToolChain &TC,
2213*0a6a1f1dSLionel Sambuc ArgStringList &CmdArgs) {
2214*0a6a1f1dSLionel Sambuc // Force linking against the system libraries sanitizers depends on
2215*0a6a1f1dSLionel Sambuc // (see PR15823 why this is necessary).
2216*0a6a1f1dSLionel Sambuc CmdArgs.push_back("--no-as-needed");
2217f4a2713aSLionel Sambuc CmdArgs.push_back("-lpthread");
2218f4a2713aSLionel Sambuc CmdArgs.push_back("-lrt");
2219f4a2713aSLionel Sambuc CmdArgs.push_back("-lm");
2220*0a6a1f1dSLionel Sambuc // There's no libdl on FreeBSD.
2221*0a6a1f1dSLionel Sambuc if (TC.getTriple().getOS() != llvm::Triple::FreeBSD)
2222*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-ldl");
2223f4a2713aSLionel Sambuc }
2224f4a2713aSLionel Sambuc
2225*0a6a1f1dSLionel Sambuc static void
collectSanitizerRuntimes(const ToolChain & TC,const ArgList & Args,SmallVectorImpl<StringRef> & SharedRuntimes,SmallVectorImpl<StringRef> & StaticRuntimes,SmallVectorImpl<StringRef> & HelperStaticRuntimes)2226*0a6a1f1dSLionel Sambuc collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
2227*0a6a1f1dSLionel Sambuc SmallVectorImpl<StringRef> &SharedRuntimes,
2228*0a6a1f1dSLionel Sambuc SmallVectorImpl<StringRef> &StaticRuntimes,
2229*0a6a1f1dSLionel Sambuc SmallVectorImpl<StringRef> &HelperStaticRuntimes) {
2230*0a6a1f1dSLionel Sambuc const SanitizerArgs &SanArgs = TC.getSanitizerArgs();
2231*0a6a1f1dSLionel Sambuc // Collect shared runtimes.
2232*0a6a1f1dSLionel Sambuc if (SanArgs.needsAsanRt() && SanArgs.needsSharedAsanRt()) {
2233*0a6a1f1dSLionel Sambuc SharedRuntimes.push_back("asan");
2234*0a6a1f1dSLionel Sambuc }
2235*0a6a1f1dSLionel Sambuc
2236*0a6a1f1dSLionel Sambuc // Collect static runtimes.
2237*0a6a1f1dSLionel Sambuc if (Args.hasArg(options::OPT_shared) ||
2238*0a6a1f1dSLionel Sambuc (TC.getTriple().getEnvironment() == llvm::Triple::Android)) {
2239*0a6a1f1dSLionel Sambuc // Don't link static runtimes into DSOs or if compiling for Android.
2240*0a6a1f1dSLionel Sambuc return;
2241*0a6a1f1dSLionel Sambuc }
2242*0a6a1f1dSLionel Sambuc if (SanArgs.needsAsanRt()) {
2243*0a6a1f1dSLionel Sambuc if (SanArgs.needsSharedAsanRt()) {
2244*0a6a1f1dSLionel Sambuc HelperStaticRuntimes.push_back("asan-preinit");
2245f4a2713aSLionel Sambuc } else {
2246*0a6a1f1dSLionel Sambuc StaticRuntimes.push_back("asan");
2247*0a6a1f1dSLionel Sambuc if (SanArgs.linkCXXRuntimes())
2248*0a6a1f1dSLionel Sambuc StaticRuntimes.push_back("asan_cxx");
2249*0a6a1f1dSLionel Sambuc }
2250*0a6a1f1dSLionel Sambuc }
2251*0a6a1f1dSLionel Sambuc if (SanArgs.needsDfsanRt())
2252*0a6a1f1dSLionel Sambuc StaticRuntimes.push_back("dfsan");
2253*0a6a1f1dSLionel Sambuc if (SanArgs.needsLsanRt())
2254*0a6a1f1dSLionel Sambuc StaticRuntimes.push_back("lsan");
2255*0a6a1f1dSLionel Sambuc if (SanArgs.needsMsanRt())
2256*0a6a1f1dSLionel Sambuc StaticRuntimes.push_back("msan");
2257*0a6a1f1dSLionel Sambuc if (SanArgs.needsTsanRt())
2258*0a6a1f1dSLionel Sambuc StaticRuntimes.push_back("tsan");
2259*0a6a1f1dSLionel Sambuc // WARNING: UBSan should always go last.
2260*0a6a1f1dSLionel Sambuc if (SanArgs.needsUbsanRt()) {
2261*0a6a1f1dSLionel Sambuc // If UBSan is not combined with another sanitizer, we need to pull in
2262*0a6a1f1dSLionel Sambuc // sanitizer_common explicitly.
2263*0a6a1f1dSLionel Sambuc if (StaticRuntimes.empty())
2264*0a6a1f1dSLionel Sambuc HelperStaticRuntimes.push_back("san");
2265*0a6a1f1dSLionel Sambuc StaticRuntimes.push_back("ubsan");
2266*0a6a1f1dSLionel Sambuc if (SanArgs.linkCXXRuntimes())
2267*0a6a1f1dSLionel Sambuc StaticRuntimes.push_back("ubsan_cxx");
2268f4a2713aSLionel Sambuc }
2269f4a2713aSLionel Sambuc }
2270f4a2713aSLionel Sambuc
2271*0a6a1f1dSLionel Sambuc // Should be called before we add system libraries (C++ ABI, libstdc++/libc++,
2272*0a6a1f1dSLionel Sambuc // C runtime, etc). Returns true if sanitizer system deps need to be linked in.
addSanitizerRuntimes(const ToolChain & TC,const ArgList & Args,ArgStringList & CmdArgs)2273*0a6a1f1dSLionel Sambuc static bool addSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
2274f4a2713aSLionel Sambuc ArgStringList &CmdArgs) {
2275*0a6a1f1dSLionel Sambuc SmallVector<StringRef, 4> SharedRuntimes, StaticRuntimes,
2276*0a6a1f1dSLionel Sambuc HelperStaticRuntimes;
2277*0a6a1f1dSLionel Sambuc collectSanitizerRuntimes(TC, Args, SharedRuntimes, StaticRuntimes,
2278*0a6a1f1dSLionel Sambuc HelperStaticRuntimes);
2279*0a6a1f1dSLionel Sambuc for (auto RT : SharedRuntimes)
2280*0a6a1f1dSLionel Sambuc addSanitizerRuntime(TC, Args, CmdArgs, RT, true);
2281*0a6a1f1dSLionel Sambuc for (auto RT : HelperStaticRuntimes)
2282*0a6a1f1dSLionel Sambuc addSanitizerRuntime(TC, Args, CmdArgs, RT, false);
2283*0a6a1f1dSLionel Sambuc bool AddExportDynamic = false;
2284*0a6a1f1dSLionel Sambuc for (auto RT : StaticRuntimes) {
2285*0a6a1f1dSLionel Sambuc addSanitizerRuntime(TC, Args, CmdArgs, RT, false);
2286*0a6a1f1dSLionel Sambuc AddExportDynamic |= !addSanitizerDynamicList(TC, Args, CmdArgs, RT);
2287f4a2713aSLionel Sambuc }
2288*0a6a1f1dSLionel Sambuc // If there is a static runtime with no dynamic list, force all the symbols
2289*0a6a1f1dSLionel Sambuc // to be dynamic to be sure we export sanitizer interface functions.
2290*0a6a1f1dSLionel Sambuc if (AddExportDynamic)
2291*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-export-dynamic");
2292*0a6a1f1dSLionel Sambuc return !StaticRuntimes.empty();
2293f4a2713aSLionel Sambuc }
2294f4a2713aSLionel Sambuc
shouldUseFramePointerForTarget(const ArgList & Args,const llvm::Triple & Triple)2295f4a2713aSLionel Sambuc static bool shouldUseFramePointerForTarget(const ArgList &Args,
2296f4a2713aSLionel Sambuc const llvm::Triple &Triple) {
2297f4a2713aSLionel Sambuc switch (Triple.getArch()) {
2298f4a2713aSLionel Sambuc // Don't use a frame pointer on linux if optimizing for certain targets.
2299f4a2713aSLionel Sambuc case llvm::Triple::mips64:
2300f4a2713aSLionel Sambuc case llvm::Triple::mips64el:
2301f4a2713aSLionel Sambuc case llvm::Triple::mips:
2302f4a2713aSLionel Sambuc case llvm::Triple::mipsel:
2303f4a2713aSLionel Sambuc case llvm::Triple::systemz:
2304f4a2713aSLionel Sambuc case llvm::Triple::x86:
2305f4a2713aSLionel Sambuc case llvm::Triple::x86_64:
2306f4a2713aSLionel Sambuc if (Triple.isOSLinux())
2307f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_O_Group))
2308f4a2713aSLionel Sambuc if (!A->getOption().matches(options::OPT_O0))
2309f4a2713aSLionel Sambuc return false;
2310f4a2713aSLionel Sambuc return true;
2311f4a2713aSLionel Sambuc case llvm::Triple::xcore:
2312f4a2713aSLionel Sambuc return false;
2313f4a2713aSLionel Sambuc default:
2314f4a2713aSLionel Sambuc return true;
2315f4a2713aSLionel Sambuc }
2316f4a2713aSLionel Sambuc }
2317f4a2713aSLionel Sambuc
shouldUseFramePointer(const ArgList & Args,const llvm::Triple & Triple)2318f4a2713aSLionel Sambuc static bool shouldUseFramePointer(const ArgList &Args,
2319f4a2713aSLionel Sambuc const llvm::Triple &Triple) {
2320f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_fno_omit_frame_pointer,
2321f4a2713aSLionel Sambuc options::OPT_fomit_frame_pointer))
2322f4a2713aSLionel Sambuc return A->getOption().matches(options::OPT_fno_omit_frame_pointer);
2323f4a2713aSLionel Sambuc
2324f4a2713aSLionel Sambuc return shouldUseFramePointerForTarget(Args, Triple);
2325f4a2713aSLionel Sambuc }
2326f4a2713aSLionel Sambuc
shouldUseLeafFramePointer(const ArgList & Args,const llvm::Triple & Triple)2327f4a2713aSLionel Sambuc static bool shouldUseLeafFramePointer(const ArgList &Args,
2328f4a2713aSLionel Sambuc const llvm::Triple &Triple) {
2329f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_mno_omit_leaf_frame_pointer,
2330f4a2713aSLionel Sambuc options::OPT_momit_leaf_frame_pointer))
2331f4a2713aSLionel Sambuc return A->getOption().matches(options::OPT_mno_omit_leaf_frame_pointer);
2332f4a2713aSLionel Sambuc
2333f4a2713aSLionel Sambuc return shouldUseFramePointerForTarget(Args, Triple);
2334f4a2713aSLionel Sambuc }
2335f4a2713aSLionel Sambuc
2336f4a2713aSLionel Sambuc /// Add a CC1 option to specify the debug compilation directory.
addDebugCompDirArg(const ArgList & Args,ArgStringList & CmdArgs)2337f4a2713aSLionel Sambuc static void addDebugCompDirArg(const ArgList &Args, ArgStringList &CmdArgs) {
2338f4a2713aSLionel Sambuc SmallString<128> cwd;
2339f4a2713aSLionel Sambuc if (!llvm::sys::fs::current_path(cwd)) {
2340f4a2713aSLionel Sambuc CmdArgs.push_back("-fdebug-compilation-dir");
2341f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(cwd));
2342f4a2713aSLionel Sambuc }
2343f4a2713aSLionel Sambuc }
2344f4a2713aSLionel Sambuc
SplitDebugName(const ArgList & Args,const InputInfoList & Inputs)2345f4a2713aSLionel Sambuc static const char *SplitDebugName(const ArgList &Args,
2346f4a2713aSLionel Sambuc const InputInfoList &Inputs) {
2347f4a2713aSLionel Sambuc Arg *FinalOutput = Args.getLastArg(options::OPT_o);
2348f4a2713aSLionel Sambuc if (FinalOutput && Args.hasArg(options::OPT_c)) {
2349f4a2713aSLionel Sambuc SmallString<128> T(FinalOutput->getValue());
2350f4a2713aSLionel Sambuc llvm::sys::path::replace_extension(T, "dwo");
2351f4a2713aSLionel Sambuc return Args.MakeArgString(T);
2352f4a2713aSLionel Sambuc } else {
2353f4a2713aSLionel Sambuc // Use the compilation dir.
2354*0a6a1f1dSLionel Sambuc SmallString<128> T(
2355*0a6a1f1dSLionel Sambuc Args.getLastArgValue(options::OPT_fdebug_compilation_dir));
2356f4a2713aSLionel Sambuc SmallString<128> F(llvm::sys::path::stem(Inputs[0].getBaseInput()));
2357f4a2713aSLionel Sambuc llvm::sys::path::replace_extension(F, "dwo");
2358f4a2713aSLionel Sambuc T += F;
2359f4a2713aSLionel Sambuc return Args.MakeArgString(F);
2360f4a2713aSLionel Sambuc }
2361f4a2713aSLionel Sambuc }
2362f4a2713aSLionel Sambuc
SplitDebugInfo(const ToolChain & TC,Compilation & C,const Tool & T,const JobAction & JA,const ArgList & Args,const InputInfo & Output,const char * OutFile)2363f4a2713aSLionel Sambuc static void SplitDebugInfo(const ToolChain &TC, Compilation &C,
2364f4a2713aSLionel Sambuc const Tool &T, const JobAction &JA,
2365f4a2713aSLionel Sambuc const ArgList &Args, const InputInfo &Output,
2366f4a2713aSLionel Sambuc const char *OutFile) {
2367f4a2713aSLionel Sambuc ArgStringList ExtractArgs;
2368f4a2713aSLionel Sambuc ExtractArgs.push_back("--extract-dwo");
2369f4a2713aSLionel Sambuc
2370f4a2713aSLionel Sambuc ArgStringList StripArgs;
2371f4a2713aSLionel Sambuc StripArgs.push_back("--strip-dwo");
2372f4a2713aSLionel Sambuc
2373f4a2713aSLionel Sambuc // Grabbing the output of the earlier compile step.
2374f4a2713aSLionel Sambuc StripArgs.push_back(Output.getFilename());
2375f4a2713aSLionel Sambuc ExtractArgs.push_back(Output.getFilename());
2376f4a2713aSLionel Sambuc ExtractArgs.push_back(OutFile);
2377f4a2713aSLionel Sambuc
2378f4a2713aSLionel Sambuc const char *Exec =
2379f4a2713aSLionel Sambuc Args.MakeArgString(TC.GetProgramPath("objcopy"));
2380f4a2713aSLionel Sambuc
2381f4a2713aSLionel Sambuc // First extract the dwo sections.
2382*0a6a1f1dSLionel Sambuc C.addCommand(llvm::make_unique<Command>(JA, T, Exec, ExtractArgs));
2383f4a2713aSLionel Sambuc
2384f4a2713aSLionel Sambuc // Then remove them from the original .o file.
2385*0a6a1f1dSLionel Sambuc C.addCommand(llvm::make_unique<Command>(JA, T, Exec, StripArgs));
2386f4a2713aSLionel Sambuc }
2387f4a2713aSLionel Sambuc
2388f4a2713aSLionel Sambuc /// \brief Vectorize at all optimization levels greater than 1 except for -Oz.
2389*0a6a1f1dSLionel Sambuc /// For -Oz the loop vectorizer is disable, while the slp vectorizer is enabled.
shouldEnableVectorizerAtOLevel(const ArgList & Args,bool isSlpVec)2390*0a6a1f1dSLionel Sambuc static bool shouldEnableVectorizerAtOLevel(const ArgList &Args, bool isSlpVec) {
2391f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
2392f4a2713aSLionel Sambuc if (A->getOption().matches(options::OPT_O4) ||
2393f4a2713aSLionel Sambuc A->getOption().matches(options::OPT_Ofast))
2394f4a2713aSLionel Sambuc return true;
2395f4a2713aSLionel Sambuc
2396f4a2713aSLionel Sambuc if (A->getOption().matches(options::OPT_O0))
2397f4a2713aSLionel Sambuc return false;
2398f4a2713aSLionel Sambuc
2399f4a2713aSLionel Sambuc assert(A->getOption().matches(options::OPT_O) && "Must have a -O flag");
2400f4a2713aSLionel Sambuc
2401f4a2713aSLionel Sambuc // Vectorize -Os.
2402f4a2713aSLionel Sambuc StringRef S(A->getValue());
2403f4a2713aSLionel Sambuc if (S == "s")
2404f4a2713aSLionel Sambuc return true;
2405f4a2713aSLionel Sambuc
2406*0a6a1f1dSLionel Sambuc // Don't vectorize -Oz, unless it's the slp vectorizer.
2407f4a2713aSLionel Sambuc if (S == "z")
2408*0a6a1f1dSLionel Sambuc return isSlpVec;
2409f4a2713aSLionel Sambuc
2410f4a2713aSLionel Sambuc unsigned OptLevel = 0;
2411f4a2713aSLionel Sambuc if (S.getAsInteger(10, OptLevel))
2412f4a2713aSLionel Sambuc return false;
2413f4a2713aSLionel Sambuc
2414f4a2713aSLionel Sambuc return OptLevel > 1;
2415f4a2713aSLionel Sambuc }
2416f4a2713aSLionel Sambuc
2417f4a2713aSLionel Sambuc return false;
2418f4a2713aSLionel Sambuc }
2419f4a2713aSLionel Sambuc
2420*0a6a1f1dSLionel Sambuc /// Add -x lang to \p CmdArgs for \p Input.
addDashXForInput(const ArgList & Args,const InputInfo & Input,ArgStringList & CmdArgs)2421*0a6a1f1dSLionel Sambuc static void addDashXForInput(const ArgList &Args, const InputInfo &Input,
2422*0a6a1f1dSLionel Sambuc ArgStringList &CmdArgs) {
2423*0a6a1f1dSLionel Sambuc // When using -verify-pch, we don't want to provide the type
2424*0a6a1f1dSLionel Sambuc // 'precompiled-header' if it was inferred from the file extension
2425*0a6a1f1dSLionel Sambuc if (Args.hasArg(options::OPT_verify_pch) && Input.getType() == types::TY_PCH)
2426*0a6a1f1dSLionel Sambuc return;
2427*0a6a1f1dSLionel Sambuc
2428*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-x");
2429*0a6a1f1dSLionel Sambuc if (Args.hasArg(options::OPT_rewrite_objc))
2430*0a6a1f1dSLionel Sambuc CmdArgs.push_back(types::getTypeName(types::TY_PP_ObjCXX));
2431*0a6a1f1dSLionel Sambuc else
2432*0a6a1f1dSLionel Sambuc CmdArgs.push_back(types::getTypeName(Input.getType()));
2433*0a6a1f1dSLionel Sambuc }
2434*0a6a1f1dSLionel Sambuc
getMSCompatibilityVersion(const char * VersionStr)2435*0a6a1f1dSLionel Sambuc static std::string getMSCompatibilityVersion(const char *VersionStr) {
2436*0a6a1f1dSLionel Sambuc unsigned Version;
2437*0a6a1f1dSLionel Sambuc if (StringRef(VersionStr).getAsInteger(10, Version))
2438*0a6a1f1dSLionel Sambuc return "0";
2439*0a6a1f1dSLionel Sambuc
2440*0a6a1f1dSLionel Sambuc if (Version < 100)
2441*0a6a1f1dSLionel Sambuc return llvm::utostr_32(Version) + ".0";
2442*0a6a1f1dSLionel Sambuc
2443*0a6a1f1dSLionel Sambuc if (Version < 10000)
2444*0a6a1f1dSLionel Sambuc return llvm::utostr_32(Version / 100) + "." +
2445*0a6a1f1dSLionel Sambuc llvm::utostr_32(Version % 100);
2446*0a6a1f1dSLionel Sambuc
2447*0a6a1f1dSLionel Sambuc unsigned Build = 0, Factor = 1;
2448*0a6a1f1dSLionel Sambuc for ( ; Version > 10000; Version = Version / 10, Factor = Factor * 10)
2449*0a6a1f1dSLionel Sambuc Build = Build + (Version % 10) * Factor;
2450*0a6a1f1dSLionel Sambuc return llvm::utostr_32(Version / 100) + "." +
2451*0a6a1f1dSLionel Sambuc llvm::utostr_32(Version % 100) + "." +
2452*0a6a1f1dSLionel Sambuc llvm::utostr_32(Build);
2453*0a6a1f1dSLionel Sambuc }
2454*0a6a1f1dSLionel Sambuc
2455*0a6a1f1dSLionel Sambuc // Claim options we don't want to warn if they are unused. We do this for
2456*0a6a1f1dSLionel Sambuc // options that build systems might add but are unused when assembling or only
2457*0a6a1f1dSLionel Sambuc // running the preprocessor for example.
claimNoWarnArgs(const ArgList & Args)2458*0a6a1f1dSLionel Sambuc static void claimNoWarnArgs(const ArgList &Args) {
2459*0a6a1f1dSLionel Sambuc // Don't warn about unused -f(no-)?lto. This can happen when we're
2460*0a6a1f1dSLionel Sambuc // preprocessing, precompiling or assembling.
2461*0a6a1f1dSLionel Sambuc Args.ClaimAllArgs(options::OPT_flto);
2462*0a6a1f1dSLionel Sambuc Args.ClaimAllArgs(options::OPT_fno_lto);
2463*0a6a1f1dSLionel Sambuc }
2464*0a6a1f1dSLionel Sambuc
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const2465f4a2713aSLionel Sambuc void Clang::ConstructJob(Compilation &C, const JobAction &JA,
2466f4a2713aSLionel Sambuc const InputInfo &Output,
2467f4a2713aSLionel Sambuc const InputInfoList &Inputs,
2468f4a2713aSLionel Sambuc const ArgList &Args,
2469f4a2713aSLionel Sambuc const char *LinkingOutput) const {
2470f4a2713aSLionel Sambuc bool KernelOrKext = Args.hasArg(options::OPT_mkernel,
2471f4a2713aSLionel Sambuc options::OPT_fapple_kext);
2472f4a2713aSLionel Sambuc const Driver &D = getToolChain().getDriver();
2473f4a2713aSLionel Sambuc ArgStringList CmdArgs;
2474f4a2713aSLionel Sambuc
2475*0a6a1f1dSLionel Sambuc bool IsWindowsGNU = getToolChain().getTriple().isWindowsGNUEnvironment();
2476*0a6a1f1dSLionel Sambuc bool IsWindowsCygnus =
2477*0a6a1f1dSLionel Sambuc getToolChain().getTriple().isWindowsCygwinEnvironment();
2478*0a6a1f1dSLionel Sambuc bool IsWindowsMSVC = getToolChain().getTriple().isWindowsMSVCEnvironment();
2479*0a6a1f1dSLionel Sambuc
2480f4a2713aSLionel Sambuc assert(Inputs.size() == 1 && "Unable to handle multiple inputs.");
2481f4a2713aSLionel Sambuc
2482f4a2713aSLionel Sambuc // Invoke ourselves in -cc1 mode.
2483f4a2713aSLionel Sambuc //
2484f4a2713aSLionel Sambuc // FIXME: Implement custom jobs for internal actions.
2485f4a2713aSLionel Sambuc CmdArgs.push_back("-cc1");
2486f4a2713aSLionel Sambuc
2487f4a2713aSLionel Sambuc // Add the "effective" target triple.
2488f4a2713aSLionel Sambuc CmdArgs.push_back("-triple");
2489f4a2713aSLionel Sambuc std::string TripleStr = getToolChain().ComputeEffectiveClangTriple(Args);
2490f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(TripleStr));
2491f4a2713aSLionel Sambuc
2492*0a6a1f1dSLionel Sambuc const llvm::Triple TT(TripleStr);
2493*0a6a1f1dSLionel Sambuc if (TT.isOSWindows() && (TT.getArch() == llvm::Triple::arm ||
2494*0a6a1f1dSLionel Sambuc TT.getArch() == llvm::Triple::thumb)) {
2495*0a6a1f1dSLionel Sambuc unsigned Offset = TT.getArch() == llvm::Triple::arm ? 4 : 6;
2496*0a6a1f1dSLionel Sambuc unsigned Version;
2497*0a6a1f1dSLionel Sambuc TT.getArchName().substr(Offset).getAsInteger(10, Version);
2498*0a6a1f1dSLionel Sambuc if (Version < 7)
2499*0a6a1f1dSLionel Sambuc D.Diag(diag::err_target_unsupported_arch) << TT.getArchName()
2500*0a6a1f1dSLionel Sambuc << TripleStr;
2501*0a6a1f1dSLionel Sambuc }
2502*0a6a1f1dSLionel Sambuc
2503*0a6a1f1dSLionel Sambuc // Push all default warning arguments that are specific to
2504*0a6a1f1dSLionel Sambuc // the given target. These come before user provided warning options
2505*0a6a1f1dSLionel Sambuc // are provided.
2506*0a6a1f1dSLionel Sambuc getToolChain().addClangWarningOptions(CmdArgs);
2507*0a6a1f1dSLionel Sambuc
2508f4a2713aSLionel Sambuc // Select the appropriate action.
2509f4a2713aSLionel Sambuc RewriteKind rewriteKind = RK_None;
2510f4a2713aSLionel Sambuc
2511f4a2713aSLionel Sambuc if (isa<AnalyzeJobAction>(JA)) {
2512f4a2713aSLionel Sambuc assert(JA.getType() == types::TY_Plist && "Invalid output type.");
2513f4a2713aSLionel Sambuc CmdArgs.push_back("-analyze");
2514f4a2713aSLionel Sambuc } else if (isa<MigrateJobAction>(JA)) {
2515f4a2713aSLionel Sambuc CmdArgs.push_back("-migrate");
2516f4a2713aSLionel Sambuc } else if (isa<PreprocessJobAction>(JA)) {
2517f4a2713aSLionel Sambuc if (Output.getType() == types::TY_Dependencies)
2518f4a2713aSLionel Sambuc CmdArgs.push_back("-Eonly");
2519f4a2713aSLionel Sambuc else {
2520f4a2713aSLionel Sambuc CmdArgs.push_back("-E");
2521f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_rewrite_objc) &&
2522f4a2713aSLionel Sambuc !Args.hasArg(options::OPT_g_Group))
2523f4a2713aSLionel Sambuc CmdArgs.push_back("-P");
2524f4a2713aSLionel Sambuc }
2525f4a2713aSLionel Sambuc } else if (isa<AssembleJobAction>(JA)) {
2526f4a2713aSLionel Sambuc CmdArgs.push_back("-emit-obj");
2527f4a2713aSLionel Sambuc
2528f4a2713aSLionel Sambuc CollectArgsForIntegratedAssembler(C, Args, CmdArgs, D);
2529f4a2713aSLionel Sambuc
2530f4a2713aSLionel Sambuc // Also ignore explicit -force_cpusubtype_ALL option.
2531f4a2713aSLionel Sambuc (void) Args.hasArg(options::OPT_force__cpusubtype__ALL);
2532f4a2713aSLionel Sambuc } else if (isa<PrecompileJobAction>(JA)) {
2533f4a2713aSLionel Sambuc // Use PCH if the user requested it.
2534f4a2713aSLionel Sambuc bool UsePCH = D.CCCUsePCH;
2535f4a2713aSLionel Sambuc
2536f4a2713aSLionel Sambuc if (JA.getType() == types::TY_Nothing)
2537f4a2713aSLionel Sambuc CmdArgs.push_back("-fsyntax-only");
2538f4a2713aSLionel Sambuc else if (UsePCH)
2539f4a2713aSLionel Sambuc CmdArgs.push_back("-emit-pch");
2540f4a2713aSLionel Sambuc else
2541f4a2713aSLionel Sambuc CmdArgs.push_back("-emit-pth");
2542*0a6a1f1dSLionel Sambuc } else if (isa<VerifyPCHJobAction>(JA)) {
2543*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-verify-pch");
2544f4a2713aSLionel Sambuc } else {
2545*0a6a1f1dSLionel Sambuc assert((isa<CompileJobAction>(JA) || isa<BackendJobAction>(JA)) &&
2546*0a6a1f1dSLionel Sambuc "Invalid action for clang tool.");
2547f4a2713aSLionel Sambuc
2548f4a2713aSLionel Sambuc if (JA.getType() == types::TY_Nothing) {
2549f4a2713aSLionel Sambuc CmdArgs.push_back("-fsyntax-only");
2550f4a2713aSLionel Sambuc } else if (JA.getType() == types::TY_LLVM_IR ||
2551f4a2713aSLionel Sambuc JA.getType() == types::TY_LTO_IR) {
2552f4a2713aSLionel Sambuc CmdArgs.push_back("-emit-llvm");
2553f4a2713aSLionel Sambuc } else if (JA.getType() == types::TY_LLVM_BC ||
2554f4a2713aSLionel Sambuc JA.getType() == types::TY_LTO_BC) {
2555f4a2713aSLionel Sambuc CmdArgs.push_back("-emit-llvm-bc");
2556f4a2713aSLionel Sambuc } else if (JA.getType() == types::TY_PP_Asm) {
2557f4a2713aSLionel Sambuc CmdArgs.push_back("-S");
2558f4a2713aSLionel Sambuc } else if (JA.getType() == types::TY_AST) {
2559f4a2713aSLionel Sambuc CmdArgs.push_back("-emit-pch");
2560f4a2713aSLionel Sambuc } else if (JA.getType() == types::TY_ModuleFile) {
2561f4a2713aSLionel Sambuc CmdArgs.push_back("-module-file-info");
2562f4a2713aSLionel Sambuc } else if (JA.getType() == types::TY_RewrittenObjC) {
2563f4a2713aSLionel Sambuc CmdArgs.push_back("-rewrite-objc");
2564f4a2713aSLionel Sambuc rewriteKind = RK_NonFragile;
2565f4a2713aSLionel Sambuc } else if (JA.getType() == types::TY_RewrittenLegacyObjC) {
2566f4a2713aSLionel Sambuc CmdArgs.push_back("-rewrite-objc");
2567f4a2713aSLionel Sambuc rewriteKind = RK_Fragile;
2568f4a2713aSLionel Sambuc } else {
2569f4a2713aSLionel Sambuc assert(JA.getType() == types::TY_PP_Asm &&
2570f4a2713aSLionel Sambuc "Unexpected output type!");
2571f4a2713aSLionel Sambuc }
2572f4a2713aSLionel Sambuc }
2573f4a2713aSLionel Sambuc
2574*0a6a1f1dSLionel Sambuc // We normally speed up the clang process a bit by skipping destructors at
2575*0a6a1f1dSLionel Sambuc // exit, but when we're generating diagnostics we can rely on some of the
2576*0a6a1f1dSLionel Sambuc // cleanup.
2577*0a6a1f1dSLionel Sambuc if (!C.isForDiagnostics())
2578f4a2713aSLionel Sambuc CmdArgs.push_back("-disable-free");
2579f4a2713aSLionel Sambuc
2580f4a2713aSLionel Sambuc // Disable the verification pass in -asserts builds.
2581f4a2713aSLionel Sambuc #ifdef NDEBUG
2582f4a2713aSLionel Sambuc CmdArgs.push_back("-disable-llvm-verifier");
2583f4a2713aSLionel Sambuc #endif
2584f4a2713aSLionel Sambuc
2585f4a2713aSLionel Sambuc // Set the main file name, so that debug info works even with
2586f4a2713aSLionel Sambuc // -save-temps.
2587f4a2713aSLionel Sambuc CmdArgs.push_back("-main-file-name");
2588f4a2713aSLionel Sambuc CmdArgs.push_back(getBaseInputName(Args, Inputs));
2589f4a2713aSLionel Sambuc
2590f4a2713aSLionel Sambuc // Some flags which affect the language (via preprocessor
2591f4a2713aSLionel Sambuc // defines).
2592f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_static))
2593f4a2713aSLionel Sambuc CmdArgs.push_back("-static-define");
2594f4a2713aSLionel Sambuc
2595f4a2713aSLionel Sambuc if (isa<AnalyzeJobAction>(JA)) {
2596f4a2713aSLionel Sambuc // Enable region store model by default.
2597f4a2713aSLionel Sambuc CmdArgs.push_back("-analyzer-store=region");
2598f4a2713aSLionel Sambuc
2599f4a2713aSLionel Sambuc // Treat blocks as analysis entry points.
2600f4a2713aSLionel Sambuc CmdArgs.push_back("-analyzer-opt-analyze-nested-blocks");
2601f4a2713aSLionel Sambuc
2602f4a2713aSLionel Sambuc CmdArgs.push_back("-analyzer-eagerly-assume");
2603f4a2713aSLionel Sambuc
2604f4a2713aSLionel Sambuc // Add default argument set.
2605f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT__analyzer_no_default_checks)) {
2606f4a2713aSLionel Sambuc CmdArgs.push_back("-analyzer-checker=core");
2607f4a2713aSLionel Sambuc
2608*0a6a1f1dSLionel Sambuc if (!IsWindowsMSVC)
2609f4a2713aSLionel Sambuc CmdArgs.push_back("-analyzer-checker=unix");
2610f4a2713aSLionel Sambuc
2611f4a2713aSLionel Sambuc if (getToolChain().getTriple().getVendor() == llvm::Triple::Apple)
2612f4a2713aSLionel Sambuc CmdArgs.push_back("-analyzer-checker=osx");
2613f4a2713aSLionel Sambuc
2614f4a2713aSLionel Sambuc CmdArgs.push_back("-analyzer-checker=deadcode");
2615f4a2713aSLionel Sambuc
2616f4a2713aSLionel Sambuc if (types::isCXX(Inputs[0].getType()))
2617f4a2713aSLionel Sambuc CmdArgs.push_back("-analyzer-checker=cplusplus");
2618f4a2713aSLionel Sambuc
2619f4a2713aSLionel Sambuc // Enable the following experimental checkers for testing.
2620*0a6a1f1dSLionel Sambuc CmdArgs.push_back(
2621*0a6a1f1dSLionel Sambuc "-analyzer-checker=security.insecureAPI.UncheckedReturn");
2622f4a2713aSLionel Sambuc CmdArgs.push_back("-analyzer-checker=security.insecureAPI.getpw");
2623f4a2713aSLionel Sambuc CmdArgs.push_back("-analyzer-checker=security.insecureAPI.gets");
2624f4a2713aSLionel Sambuc CmdArgs.push_back("-analyzer-checker=security.insecureAPI.mktemp");
2625f4a2713aSLionel Sambuc CmdArgs.push_back("-analyzer-checker=security.insecureAPI.mkstemp");
2626f4a2713aSLionel Sambuc CmdArgs.push_back("-analyzer-checker=security.insecureAPI.vfork");
2627f4a2713aSLionel Sambuc }
2628f4a2713aSLionel Sambuc
2629f4a2713aSLionel Sambuc // Set the output format. The default is plist, for (lame) historical
2630f4a2713aSLionel Sambuc // reasons.
2631f4a2713aSLionel Sambuc CmdArgs.push_back("-analyzer-output");
2632f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT__analyzer_output))
2633f4a2713aSLionel Sambuc CmdArgs.push_back(A->getValue());
2634f4a2713aSLionel Sambuc else
2635f4a2713aSLionel Sambuc CmdArgs.push_back("plist");
2636f4a2713aSLionel Sambuc
2637f4a2713aSLionel Sambuc // Disable the presentation of standard compiler warnings when
2638f4a2713aSLionel Sambuc // using --analyze. We only want to show static analyzer diagnostics
2639f4a2713aSLionel Sambuc // or frontend errors.
2640f4a2713aSLionel Sambuc CmdArgs.push_back("-w");
2641f4a2713aSLionel Sambuc
2642f4a2713aSLionel Sambuc // Add -Xanalyzer arguments when running as analyzer.
2643f4a2713aSLionel Sambuc Args.AddAllArgValues(CmdArgs, options::OPT_Xanalyzer);
2644f4a2713aSLionel Sambuc }
2645f4a2713aSLionel Sambuc
2646f4a2713aSLionel Sambuc CheckCodeGenerationOptions(D, Args);
2647f4a2713aSLionel Sambuc
2648f4a2713aSLionel Sambuc bool PIE = getToolChain().isPIEDefault();
2649f4a2713aSLionel Sambuc bool PIC = PIE || getToolChain().isPICDefault();
2650f4a2713aSLionel Sambuc bool IsPICLevelTwo = PIC;
2651f4a2713aSLionel Sambuc
2652*0a6a1f1dSLionel Sambuc // Android-specific defaults for PIC/PIE
2653*0a6a1f1dSLionel Sambuc if (getToolChain().getTriple().getEnvironment() == llvm::Triple::Android) {
2654*0a6a1f1dSLionel Sambuc switch (getToolChain().getTriple().getArch()) {
2655*0a6a1f1dSLionel Sambuc case llvm::Triple::arm:
2656*0a6a1f1dSLionel Sambuc case llvm::Triple::armeb:
2657*0a6a1f1dSLionel Sambuc case llvm::Triple::thumb:
2658*0a6a1f1dSLionel Sambuc case llvm::Triple::thumbeb:
2659*0a6a1f1dSLionel Sambuc case llvm::Triple::aarch64:
2660*0a6a1f1dSLionel Sambuc case llvm::Triple::mips:
2661*0a6a1f1dSLionel Sambuc case llvm::Triple::mipsel:
2662*0a6a1f1dSLionel Sambuc case llvm::Triple::mips64:
2663*0a6a1f1dSLionel Sambuc case llvm::Triple::mips64el:
2664*0a6a1f1dSLionel Sambuc PIC = true; // "-fpic"
2665*0a6a1f1dSLionel Sambuc break;
2666*0a6a1f1dSLionel Sambuc
2667*0a6a1f1dSLionel Sambuc case llvm::Triple::x86:
2668*0a6a1f1dSLionel Sambuc case llvm::Triple::x86_64:
2669*0a6a1f1dSLionel Sambuc PIC = true; // "-fPIC"
2670*0a6a1f1dSLionel Sambuc IsPICLevelTwo = true;
2671*0a6a1f1dSLionel Sambuc break;
2672*0a6a1f1dSLionel Sambuc
2673*0a6a1f1dSLionel Sambuc default:
2674*0a6a1f1dSLionel Sambuc break;
2675*0a6a1f1dSLionel Sambuc }
2676*0a6a1f1dSLionel Sambuc }
2677*0a6a1f1dSLionel Sambuc
2678*0a6a1f1dSLionel Sambuc // OpenBSD-specific defaults for PIE
2679*0a6a1f1dSLionel Sambuc if (getToolChain().getTriple().getOS() == llvm::Triple::OpenBSD) {
2680*0a6a1f1dSLionel Sambuc switch (getToolChain().getTriple().getArch()) {
2681*0a6a1f1dSLionel Sambuc case llvm::Triple::mips64:
2682*0a6a1f1dSLionel Sambuc case llvm::Triple::mips64el:
2683*0a6a1f1dSLionel Sambuc case llvm::Triple::sparc:
2684*0a6a1f1dSLionel Sambuc case llvm::Triple::x86:
2685*0a6a1f1dSLionel Sambuc case llvm::Triple::x86_64:
2686*0a6a1f1dSLionel Sambuc IsPICLevelTwo = false; // "-fpie"
2687*0a6a1f1dSLionel Sambuc break;
2688*0a6a1f1dSLionel Sambuc
2689*0a6a1f1dSLionel Sambuc case llvm::Triple::ppc:
2690*0a6a1f1dSLionel Sambuc case llvm::Triple::sparcv9:
2691*0a6a1f1dSLionel Sambuc IsPICLevelTwo = true; // "-fPIE"
2692*0a6a1f1dSLionel Sambuc break;
2693*0a6a1f1dSLionel Sambuc
2694*0a6a1f1dSLionel Sambuc default:
2695*0a6a1f1dSLionel Sambuc break;
2696*0a6a1f1dSLionel Sambuc }
2697*0a6a1f1dSLionel Sambuc }
2698*0a6a1f1dSLionel Sambuc
2699f4a2713aSLionel Sambuc // For the PIC and PIE flag options, this logic is different from the
2700f4a2713aSLionel Sambuc // legacy logic in very old versions of GCC, as that logic was just
2701f4a2713aSLionel Sambuc // a bug no one had ever fixed. This logic is both more rational and
2702f4a2713aSLionel Sambuc // consistent with GCC's new logic now that the bugs are fixed. The last
2703f4a2713aSLionel Sambuc // argument relating to either PIC or PIE wins, and no other argument is
2704f4a2713aSLionel Sambuc // used. If the last argument is any flavor of the '-fno-...' arguments,
2705f4a2713aSLionel Sambuc // both PIC and PIE are disabled. Any PIE option implicitly enables PIC
2706f4a2713aSLionel Sambuc // at the same level.
2707f4a2713aSLionel Sambuc Arg *LastPICArg =Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC,
2708f4a2713aSLionel Sambuc options::OPT_fpic, options::OPT_fno_pic,
2709f4a2713aSLionel Sambuc options::OPT_fPIE, options::OPT_fno_PIE,
2710f4a2713aSLionel Sambuc options::OPT_fpie, options::OPT_fno_pie);
2711f4a2713aSLionel Sambuc // Check whether the tool chain trumps the PIC-ness decision. If the PIC-ness
2712f4a2713aSLionel Sambuc // is forced, then neither PIC nor PIE flags will have no effect.
2713f4a2713aSLionel Sambuc if (!getToolChain().isPICDefaultForced()) {
2714f4a2713aSLionel Sambuc if (LastPICArg) {
2715f4a2713aSLionel Sambuc Option O = LastPICArg->getOption();
2716f4a2713aSLionel Sambuc if (O.matches(options::OPT_fPIC) || O.matches(options::OPT_fpic) ||
2717f4a2713aSLionel Sambuc O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie)) {
2718f4a2713aSLionel Sambuc PIE = O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie);
2719f4a2713aSLionel Sambuc PIC = PIE || O.matches(options::OPT_fPIC) ||
2720f4a2713aSLionel Sambuc O.matches(options::OPT_fpic);
2721f4a2713aSLionel Sambuc IsPICLevelTwo = O.matches(options::OPT_fPIE) ||
2722f4a2713aSLionel Sambuc O.matches(options::OPT_fPIC);
2723f4a2713aSLionel Sambuc } else {
2724f4a2713aSLionel Sambuc PIE = PIC = false;
2725f4a2713aSLionel Sambuc }
2726f4a2713aSLionel Sambuc }
2727f4a2713aSLionel Sambuc }
2728f4a2713aSLionel Sambuc
2729f4a2713aSLionel Sambuc // Introduce a Darwin-specific hack. If the default is PIC but the flags
2730f4a2713aSLionel Sambuc // specified while enabling PIC enabled level 1 PIC, just force it back to
2731f4a2713aSLionel Sambuc // level 2 PIC instead. This matches the behavior of Darwin GCC (based on my
2732f4a2713aSLionel Sambuc // informal testing).
2733f4a2713aSLionel Sambuc if (PIC && getToolChain().getTriple().isOSDarwin())
2734f4a2713aSLionel Sambuc IsPICLevelTwo |= getToolChain().isPICDefault();
2735f4a2713aSLionel Sambuc
2736f4a2713aSLionel Sambuc // Note that these flags are trump-cards. Regardless of the order w.r.t. the
2737f4a2713aSLionel Sambuc // PIC or PIE options above, if these show up, PIC is disabled.
2738f4a2713aSLionel Sambuc llvm::Triple Triple(TripleStr);
2739*0a6a1f1dSLionel Sambuc if (KernelOrKext && (!Triple.isiOS() || Triple.isOSVersionLT(6)))
2740f4a2713aSLionel Sambuc PIC = PIE = false;
2741f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_static))
2742f4a2713aSLionel Sambuc PIC = PIE = false;
2743f4a2713aSLionel Sambuc
2744f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_mdynamic_no_pic)) {
2745f4a2713aSLionel Sambuc // This is a very special mode. It trumps the other modes, almost no one
2746f4a2713aSLionel Sambuc // uses it, and it isn't even valid on any OS but Darwin.
2747f4a2713aSLionel Sambuc if (!getToolChain().getTriple().isOSDarwin())
2748f4a2713aSLionel Sambuc D.Diag(diag::err_drv_unsupported_opt_for_target)
2749f4a2713aSLionel Sambuc << A->getSpelling() << getToolChain().getTriple().str();
2750f4a2713aSLionel Sambuc
2751f4a2713aSLionel Sambuc // FIXME: Warn when this flag trumps some other PIC or PIE flag.
2752f4a2713aSLionel Sambuc
2753f4a2713aSLionel Sambuc CmdArgs.push_back("-mrelocation-model");
2754f4a2713aSLionel Sambuc CmdArgs.push_back("dynamic-no-pic");
2755f4a2713aSLionel Sambuc
2756f4a2713aSLionel Sambuc // Only a forced PIC mode can cause the actual compile to have PIC defines
2757f4a2713aSLionel Sambuc // etc., no flags are sufficient. This behavior was selected to closely
2758f4a2713aSLionel Sambuc // match that of llvm-gcc and Apple GCC before that.
2759f4a2713aSLionel Sambuc if (getToolChain().isPICDefault() && getToolChain().isPICDefaultForced()) {
2760f4a2713aSLionel Sambuc CmdArgs.push_back("-pic-level");
2761f4a2713aSLionel Sambuc CmdArgs.push_back("2");
2762f4a2713aSLionel Sambuc }
2763f4a2713aSLionel Sambuc } else {
2764f4a2713aSLionel Sambuc // Currently, LLVM only knows about PIC vs. static; the PIE differences are
2765f4a2713aSLionel Sambuc // handled in Clang's IRGen by the -pie-level flag.
2766f4a2713aSLionel Sambuc CmdArgs.push_back("-mrelocation-model");
2767f4a2713aSLionel Sambuc CmdArgs.push_back(PIC ? "pic" : "static");
2768f4a2713aSLionel Sambuc
2769f4a2713aSLionel Sambuc if (PIC) {
2770f4a2713aSLionel Sambuc CmdArgs.push_back("-pic-level");
2771f4a2713aSLionel Sambuc CmdArgs.push_back(IsPICLevelTwo ? "2" : "1");
2772f4a2713aSLionel Sambuc if (PIE) {
2773f4a2713aSLionel Sambuc CmdArgs.push_back("-pie-level");
2774f4a2713aSLionel Sambuc CmdArgs.push_back(IsPICLevelTwo ? "2" : "1");
2775f4a2713aSLionel Sambuc }
2776f4a2713aSLionel Sambuc }
2777f4a2713aSLionel Sambuc }
2778f4a2713aSLionel Sambuc
2779*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-mthread-model");
2780*0a6a1f1dSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_mthread_model))
2781*0a6a1f1dSLionel Sambuc CmdArgs.push_back(A->getValue());
2782*0a6a1f1dSLionel Sambuc else
2783*0a6a1f1dSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(getToolChain().getThreadModel()));
2784*0a6a1f1dSLionel Sambuc
2785f4a2713aSLionel Sambuc if (!Args.hasFlag(options::OPT_fmerge_all_constants,
2786f4a2713aSLionel Sambuc options::OPT_fno_merge_all_constants))
2787f4a2713aSLionel Sambuc CmdArgs.push_back("-fno-merge-all-constants");
2788f4a2713aSLionel Sambuc
2789f4a2713aSLionel Sambuc // LLVM Code Generator Options.
2790f4a2713aSLionel Sambuc
2791*0a6a1f1dSLionel Sambuc if (Args.hasArg(options::OPT_frewrite_map_file) ||
2792*0a6a1f1dSLionel Sambuc Args.hasArg(options::OPT_frewrite_map_file_EQ)) {
2793*0a6a1f1dSLionel Sambuc for (arg_iterator
2794*0a6a1f1dSLionel Sambuc MFI = Args.filtered_begin(options::OPT_frewrite_map_file,
2795*0a6a1f1dSLionel Sambuc options::OPT_frewrite_map_file_EQ),
2796*0a6a1f1dSLionel Sambuc MFE = Args.filtered_end();
2797*0a6a1f1dSLionel Sambuc MFI != MFE; ++MFI) {
2798*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-frewrite-map-file");
2799*0a6a1f1dSLionel Sambuc CmdArgs.push_back((*MFI)->getValue());
2800*0a6a1f1dSLionel Sambuc (*MFI)->claim();
2801*0a6a1f1dSLionel Sambuc }
2802*0a6a1f1dSLionel Sambuc }
2803*0a6a1f1dSLionel Sambuc
2804*0a6a1f1dSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_Wframe_larger_than_EQ)) {
2805*0a6a1f1dSLionel Sambuc StringRef v = A->getValue();
2806*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-mllvm");
2807*0a6a1f1dSLionel Sambuc CmdArgs.push_back(Args.MakeArgString("-warn-stack-size=" + v));
2808*0a6a1f1dSLionel Sambuc A->claim();
2809*0a6a1f1dSLionel Sambuc }
2810*0a6a1f1dSLionel Sambuc
2811f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_mregparm_EQ)) {
2812f4a2713aSLionel Sambuc CmdArgs.push_back("-mregparm");
2813f4a2713aSLionel Sambuc CmdArgs.push_back(A->getValue());
2814f4a2713aSLionel Sambuc }
2815f4a2713aSLionel Sambuc
2816f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_fpcc_struct_return,
2817f4a2713aSLionel Sambuc options::OPT_freg_struct_return)) {
2818f4a2713aSLionel Sambuc if (getToolChain().getArch() != llvm::Triple::x86) {
2819f4a2713aSLionel Sambuc D.Diag(diag::err_drv_unsupported_opt_for_target)
2820f4a2713aSLionel Sambuc << A->getSpelling() << getToolChain().getTriple().str();
2821f4a2713aSLionel Sambuc } else if (A->getOption().matches(options::OPT_fpcc_struct_return)) {
2822f4a2713aSLionel Sambuc CmdArgs.push_back("-fpcc-struct-return");
2823f4a2713aSLionel Sambuc } else {
2824f4a2713aSLionel Sambuc assert(A->getOption().matches(options::OPT_freg_struct_return));
2825f4a2713aSLionel Sambuc CmdArgs.push_back("-freg-struct-return");
2826f4a2713aSLionel Sambuc }
2827f4a2713aSLionel Sambuc }
2828f4a2713aSLionel Sambuc
2829f4a2713aSLionel Sambuc if (Args.hasFlag(options::OPT_mrtd, options::OPT_mno_rtd, false))
2830f4a2713aSLionel Sambuc CmdArgs.push_back("-mrtd");
2831f4a2713aSLionel Sambuc
2832f4a2713aSLionel Sambuc if (shouldUseFramePointer(Args, getToolChain().getTriple()))
2833f4a2713aSLionel Sambuc CmdArgs.push_back("-mdisable-fp-elim");
2834f4a2713aSLionel Sambuc if (!Args.hasFlag(options::OPT_fzero_initialized_in_bss,
2835f4a2713aSLionel Sambuc options::OPT_fno_zero_initialized_in_bss))
2836f4a2713aSLionel Sambuc CmdArgs.push_back("-mno-zero-initialized-in-bss");
2837f4a2713aSLionel Sambuc
2838f4a2713aSLionel Sambuc bool OFastEnabled = isOptimizationLevelFast(Args);
2839f4a2713aSLionel Sambuc // If -Ofast is the optimization level, then -fstrict-aliasing should be
2840f4a2713aSLionel Sambuc // enabled. This alias option is being used to simplify the hasFlag logic.
2841f4a2713aSLionel Sambuc OptSpecifier StrictAliasingAliasOption = OFastEnabled ? options::OPT_Ofast :
2842f4a2713aSLionel Sambuc options::OPT_fstrict_aliasing;
2843*0a6a1f1dSLionel Sambuc // We turn strict aliasing off by default if we're in CL mode, since MSVC
2844*0a6a1f1dSLionel Sambuc // doesn't do any TBAA.
2845*0a6a1f1dSLionel Sambuc bool TBAAOnByDefault = !getToolChain().getDriver().IsCLMode();
2846f4a2713aSLionel Sambuc if (!Args.hasFlag(options::OPT_fstrict_aliasing, StrictAliasingAliasOption,
2847*0a6a1f1dSLionel Sambuc options::OPT_fno_strict_aliasing, TBAAOnByDefault))
2848f4a2713aSLionel Sambuc CmdArgs.push_back("-relaxed-aliasing");
2849f4a2713aSLionel Sambuc if (!Args.hasFlag(options::OPT_fstruct_path_tbaa,
2850f4a2713aSLionel Sambuc options::OPT_fno_struct_path_tbaa))
2851f4a2713aSLionel Sambuc CmdArgs.push_back("-no-struct-path-tbaa");
2852f4a2713aSLionel Sambuc if (Args.hasFlag(options::OPT_fstrict_enums, options::OPT_fno_strict_enums,
2853f4a2713aSLionel Sambuc false))
2854f4a2713aSLionel Sambuc CmdArgs.push_back("-fstrict-enums");
2855f4a2713aSLionel Sambuc if (!Args.hasFlag(options::OPT_foptimize_sibling_calls,
2856f4a2713aSLionel Sambuc options::OPT_fno_optimize_sibling_calls))
2857f4a2713aSLionel Sambuc CmdArgs.push_back("-mdisable-tail-calls");
2858f4a2713aSLionel Sambuc
2859f4a2713aSLionel Sambuc // Handle segmented stacks.
2860f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_fsplit_stack))
2861f4a2713aSLionel Sambuc CmdArgs.push_back("-split-stacks");
2862f4a2713aSLionel Sambuc
2863f4a2713aSLionel Sambuc // If -Ofast is the optimization level, then -ffast-math should be enabled.
2864f4a2713aSLionel Sambuc // This alias option is being used to simplify the getLastArg logic.
2865f4a2713aSLionel Sambuc OptSpecifier FastMathAliasOption = OFastEnabled ? options::OPT_Ofast :
2866f4a2713aSLionel Sambuc options::OPT_ffast_math;
2867f4a2713aSLionel Sambuc
2868f4a2713aSLionel Sambuc // Handle various floating point optimization flags, mapping them to the
2869f4a2713aSLionel Sambuc // appropriate LLVM code generation flags. The pattern for all of these is to
2870f4a2713aSLionel Sambuc // default off the codegen optimizations, and if any flag enables them and no
2871f4a2713aSLionel Sambuc // flag disables them after the flag enabling them, enable the codegen
2872f4a2713aSLionel Sambuc // optimization. This is complicated by several "umbrella" flags.
2873f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption,
2874f4a2713aSLionel Sambuc options::OPT_fno_fast_math,
2875f4a2713aSLionel Sambuc options::OPT_ffinite_math_only,
2876f4a2713aSLionel Sambuc options::OPT_fno_finite_math_only,
2877f4a2713aSLionel Sambuc options::OPT_fhonor_infinities,
2878f4a2713aSLionel Sambuc options::OPT_fno_honor_infinities))
2879f4a2713aSLionel Sambuc if (A->getOption().getID() != options::OPT_fno_fast_math &&
2880f4a2713aSLionel Sambuc A->getOption().getID() != options::OPT_fno_finite_math_only &&
2881f4a2713aSLionel Sambuc A->getOption().getID() != options::OPT_fhonor_infinities)
2882f4a2713aSLionel Sambuc CmdArgs.push_back("-menable-no-infs");
2883f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption,
2884f4a2713aSLionel Sambuc options::OPT_fno_fast_math,
2885f4a2713aSLionel Sambuc options::OPT_ffinite_math_only,
2886f4a2713aSLionel Sambuc options::OPT_fno_finite_math_only,
2887f4a2713aSLionel Sambuc options::OPT_fhonor_nans,
2888f4a2713aSLionel Sambuc options::OPT_fno_honor_nans))
2889f4a2713aSLionel Sambuc if (A->getOption().getID() != options::OPT_fno_fast_math &&
2890f4a2713aSLionel Sambuc A->getOption().getID() != options::OPT_fno_finite_math_only &&
2891f4a2713aSLionel Sambuc A->getOption().getID() != options::OPT_fhonor_nans)
2892f4a2713aSLionel Sambuc CmdArgs.push_back("-menable-no-nans");
2893f4a2713aSLionel Sambuc
2894f4a2713aSLionel Sambuc // -fmath-errno is the default on some platforms, e.g. BSD-derived OSes.
2895f4a2713aSLionel Sambuc bool MathErrno = getToolChain().IsMathErrnoDefault();
2896f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption,
2897f4a2713aSLionel Sambuc options::OPT_fno_fast_math,
2898f4a2713aSLionel Sambuc options::OPT_fmath_errno,
2899f4a2713aSLionel Sambuc options::OPT_fno_math_errno)) {
2900f4a2713aSLionel Sambuc // Turning on -ffast_math (with either flag) removes the need for MathErrno.
2901f4a2713aSLionel Sambuc // However, turning *off* -ffast_math merely restores the toolchain default
2902f4a2713aSLionel Sambuc // (which may be false).
2903f4a2713aSLionel Sambuc if (A->getOption().getID() == options::OPT_fno_math_errno ||
2904f4a2713aSLionel Sambuc A->getOption().getID() == options::OPT_ffast_math ||
2905f4a2713aSLionel Sambuc A->getOption().getID() == options::OPT_Ofast)
2906f4a2713aSLionel Sambuc MathErrno = false;
2907f4a2713aSLionel Sambuc else if (A->getOption().getID() == options::OPT_fmath_errno)
2908f4a2713aSLionel Sambuc MathErrno = true;
2909f4a2713aSLionel Sambuc }
2910f4a2713aSLionel Sambuc if (MathErrno)
2911f4a2713aSLionel Sambuc CmdArgs.push_back("-fmath-errno");
2912f4a2713aSLionel Sambuc
2913f4a2713aSLionel Sambuc // There are several flags which require disabling very specific
2914f4a2713aSLionel Sambuc // optimizations. Any of these being disabled forces us to turn off the
2915f4a2713aSLionel Sambuc // entire set of LLVM optimizations, so collect them through all the flag
2916f4a2713aSLionel Sambuc // madness.
2917f4a2713aSLionel Sambuc bool AssociativeMath = false;
2918f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption,
2919f4a2713aSLionel Sambuc options::OPT_fno_fast_math,
2920f4a2713aSLionel Sambuc options::OPT_funsafe_math_optimizations,
2921f4a2713aSLionel Sambuc options::OPT_fno_unsafe_math_optimizations,
2922f4a2713aSLionel Sambuc options::OPT_fassociative_math,
2923f4a2713aSLionel Sambuc options::OPT_fno_associative_math))
2924f4a2713aSLionel Sambuc if (A->getOption().getID() != options::OPT_fno_fast_math &&
2925f4a2713aSLionel Sambuc A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations &&
2926f4a2713aSLionel Sambuc A->getOption().getID() != options::OPT_fno_associative_math)
2927f4a2713aSLionel Sambuc AssociativeMath = true;
2928f4a2713aSLionel Sambuc bool ReciprocalMath = false;
2929f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption,
2930f4a2713aSLionel Sambuc options::OPT_fno_fast_math,
2931f4a2713aSLionel Sambuc options::OPT_funsafe_math_optimizations,
2932f4a2713aSLionel Sambuc options::OPT_fno_unsafe_math_optimizations,
2933f4a2713aSLionel Sambuc options::OPT_freciprocal_math,
2934f4a2713aSLionel Sambuc options::OPT_fno_reciprocal_math))
2935f4a2713aSLionel Sambuc if (A->getOption().getID() != options::OPT_fno_fast_math &&
2936f4a2713aSLionel Sambuc A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations &&
2937f4a2713aSLionel Sambuc A->getOption().getID() != options::OPT_fno_reciprocal_math)
2938f4a2713aSLionel Sambuc ReciprocalMath = true;
2939f4a2713aSLionel Sambuc bool SignedZeros = true;
2940f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption,
2941f4a2713aSLionel Sambuc options::OPT_fno_fast_math,
2942f4a2713aSLionel Sambuc options::OPT_funsafe_math_optimizations,
2943f4a2713aSLionel Sambuc options::OPT_fno_unsafe_math_optimizations,
2944f4a2713aSLionel Sambuc options::OPT_fsigned_zeros,
2945f4a2713aSLionel Sambuc options::OPT_fno_signed_zeros))
2946f4a2713aSLionel Sambuc if (A->getOption().getID() != options::OPT_fno_fast_math &&
2947f4a2713aSLionel Sambuc A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations &&
2948f4a2713aSLionel Sambuc A->getOption().getID() != options::OPT_fsigned_zeros)
2949f4a2713aSLionel Sambuc SignedZeros = false;
2950f4a2713aSLionel Sambuc bool TrappingMath = true;
2951f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption,
2952f4a2713aSLionel Sambuc options::OPT_fno_fast_math,
2953f4a2713aSLionel Sambuc options::OPT_funsafe_math_optimizations,
2954f4a2713aSLionel Sambuc options::OPT_fno_unsafe_math_optimizations,
2955f4a2713aSLionel Sambuc options::OPT_ftrapping_math,
2956f4a2713aSLionel Sambuc options::OPT_fno_trapping_math))
2957f4a2713aSLionel Sambuc if (A->getOption().getID() != options::OPT_fno_fast_math &&
2958f4a2713aSLionel Sambuc A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations &&
2959f4a2713aSLionel Sambuc A->getOption().getID() != options::OPT_ftrapping_math)
2960f4a2713aSLionel Sambuc TrappingMath = false;
2961f4a2713aSLionel Sambuc if (!MathErrno && AssociativeMath && ReciprocalMath && !SignedZeros &&
2962f4a2713aSLionel Sambuc !TrappingMath)
2963f4a2713aSLionel Sambuc CmdArgs.push_back("-menable-unsafe-fp-math");
2964f4a2713aSLionel Sambuc
2965f4a2713aSLionel Sambuc
2966f4a2713aSLionel Sambuc // Validate and pass through -fp-contract option.
2967f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption,
2968f4a2713aSLionel Sambuc options::OPT_fno_fast_math,
2969f4a2713aSLionel Sambuc options::OPT_ffp_contract)) {
2970f4a2713aSLionel Sambuc if (A->getOption().getID() == options::OPT_ffp_contract) {
2971f4a2713aSLionel Sambuc StringRef Val = A->getValue();
2972f4a2713aSLionel Sambuc if (Val == "fast" || Val == "on" || Val == "off") {
2973f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString("-ffp-contract=" + Val));
2974f4a2713aSLionel Sambuc } else {
2975f4a2713aSLionel Sambuc D.Diag(diag::err_drv_unsupported_option_argument)
2976f4a2713aSLionel Sambuc << A->getOption().getName() << Val;
2977f4a2713aSLionel Sambuc }
2978f4a2713aSLionel Sambuc } else if (A->getOption().matches(options::OPT_ffast_math) ||
2979f4a2713aSLionel Sambuc (OFastEnabled && A->getOption().matches(options::OPT_Ofast))) {
2980f4a2713aSLionel Sambuc // If fast-math is set then set the fp-contract mode to fast.
2981f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString("-ffp-contract=fast"));
2982f4a2713aSLionel Sambuc }
2983f4a2713aSLionel Sambuc }
2984f4a2713aSLionel Sambuc
2985f4a2713aSLionel Sambuc // We separately look for the '-ffast-math' and '-ffinite-math-only' flags,
2986f4a2713aSLionel Sambuc // and if we find them, tell the frontend to provide the appropriate
2987f4a2713aSLionel Sambuc // preprocessor macros. This is distinct from enabling any optimizations as
2988f4a2713aSLionel Sambuc // these options induce language changes which must survive serialization
2989f4a2713aSLionel Sambuc // and deserialization, etc.
2990f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption,
2991f4a2713aSLionel Sambuc options::OPT_fno_fast_math))
2992f4a2713aSLionel Sambuc if (!A->getOption().matches(options::OPT_fno_fast_math))
2993f4a2713aSLionel Sambuc CmdArgs.push_back("-ffast-math");
2994*0a6a1f1dSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_ffinite_math_only,
2995*0a6a1f1dSLionel Sambuc options::OPT_fno_fast_math))
2996f4a2713aSLionel Sambuc if (A->getOption().matches(options::OPT_ffinite_math_only))
2997f4a2713aSLionel Sambuc CmdArgs.push_back("-ffinite-math-only");
2998f4a2713aSLionel Sambuc
2999f4a2713aSLionel Sambuc // Decide whether to use verbose asm. Verbose assembly is the default on
3000f4a2713aSLionel Sambuc // toolchains which have the integrated assembler on by default.
3001*0a6a1f1dSLionel Sambuc bool IsIntegratedAssemblerDefault =
3002*0a6a1f1dSLionel Sambuc getToolChain().IsIntegratedAssemblerDefault();
3003f4a2713aSLionel Sambuc if (Args.hasFlag(options::OPT_fverbose_asm, options::OPT_fno_verbose_asm,
3004*0a6a1f1dSLionel Sambuc IsIntegratedAssemblerDefault) ||
3005f4a2713aSLionel Sambuc Args.hasArg(options::OPT_dA))
3006f4a2713aSLionel Sambuc CmdArgs.push_back("-masm-verbose");
3007f4a2713aSLionel Sambuc
3008*0a6a1f1dSLionel Sambuc if (!Args.hasFlag(options::OPT_fintegrated_as, options::OPT_fno_integrated_as,
3009*0a6a1f1dSLionel Sambuc IsIntegratedAssemblerDefault))
3010*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-no-integrated-as");
3011*0a6a1f1dSLionel Sambuc
3012f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_fdebug_pass_structure)) {
3013f4a2713aSLionel Sambuc CmdArgs.push_back("-mdebug-pass");
3014f4a2713aSLionel Sambuc CmdArgs.push_back("Structure");
3015f4a2713aSLionel Sambuc }
3016f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_fdebug_pass_arguments)) {
3017f4a2713aSLionel Sambuc CmdArgs.push_back("-mdebug-pass");
3018f4a2713aSLionel Sambuc CmdArgs.push_back("Arguments");
3019f4a2713aSLionel Sambuc }
3020f4a2713aSLionel Sambuc
3021f4a2713aSLionel Sambuc // Enable -mconstructor-aliases except on darwin, where we have to
3022f4a2713aSLionel Sambuc // work around a linker bug; see <rdar://problem/7651567>.
3023f4a2713aSLionel Sambuc if (!getToolChain().getTriple().isOSDarwin())
3024f4a2713aSLionel Sambuc CmdArgs.push_back("-mconstructor-aliases");
3025f4a2713aSLionel Sambuc
3026f4a2713aSLionel Sambuc // Darwin's kernel doesn't support guard variables; just die if we
3027f4a2713aSLionel Sambuc // try to use them.
3028f4a2713aSLionel Sambuc if (KernelOrKext && getToolChain().getTriple().isOSDarwin())
3029f4a2713aSLionel Sambuc CmdArgs.push_back("-fforbid-guard-variables");
3030f4a2713aSLionel Sambuc
3031f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_mms_bitfields)) {
3032f4a2713aSLionel Sambuc CmdArgs.push_back("-mms-bitfields");
3033f4a2713aSLionel Sambuc }
3034f4a2713aSLionel Sambuc
3035f4a2713aSLionel Sambuc // This is a coarse approximation of what llvm-gcc actually does, both
3036f4a2713aSLionel Sambuc // -fasynchronous-unwind-tables and -fnon-call-exceptions interact in more
3037f4a2713aSLionel Sambuc // complicated ways.
3038f4a2713aSLionel Sambuc bool AsynchronousUnwindTables =
3039f4a2713aSLionel Sambuc Args.hasFlag(options::OPT_fasynchronous_unwind_tables,
3040f4a2713aSLionel Sambuc options::OPT_fno_asynchronous_unwind_tables,
3041*0a6a1f1dSLionel Sambuc (getToolChain().IsUnwindTablesDefault() ||
3042*0a6a1f1dSLionel Sambuc getToolChain().getSanitizerArgs().needsUnwindTables()) &&
3043f4a2713aSLionel Sambuc !KernelOrKext);
3044f4a2713aSLionel Sambuc if (Args.hasFlag(options::OPT_funwind_tables, options::OPT_fno_unwind_tables,
3045f4a2713aSLionel Sambuc AsynchronousUnwindTables))
3046f4a2713aSLionel Sambuc CmdArgs.push_back("-munwind-tables");
3047f4a2713aSLionel Sambuc
3048f4a2713aSLionel Sambuc getToolChain().addClangTargetOptions(Args, CmdArgs);
3049f4a2713aSLionel Sambuc
3050f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_flimited_precision_EQ)) {
3051f4a2713aSLionel Sambuc CmdArgs.push_back("-mlimit-float-precision");
3052f4a2713aSLionel Sambuc CmdArgs.push_back(A->getValue());
3053f4a2713aSLionel Sambuc }
3054f4a2713aSLionel Sambuc
3055f4a2713aSLionel Sambuc // FIXME: Handle -mtune=.
3056f4a2713aSLionel Sambuc (void) Args.hasArg(options::OPT_mtune_EQ);
3057f4a2713aSLionel Sambuc
3058f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_mcmodel_EQ)) {
3059f4a2713aSLionel Sambuc CmdArgs.push_back("-mcode-model");
3060f4a2713aSLionel Sambuc CmdArgs.push_back(A->getValue());
3061f4a2713aSLionel Sambuc }
3062f4a2713aSLionel Sambuc
3063f4a2713aSLionel Sambuc // Add the target cpu
3064f4a2713aSLionel Sambuc std::string ETripleStr = getToolChain().ComputeEffectiveClangTriple(Args);
3065f4a2713aSLionel Sambuc llvm::Triple ETriple(ETripleStr);
3066f4a2713aSLionel Sambuc std::string CPU = getCPUName(Args, ETriple);
3067f4a2713aSLionel Sambuc if (!CPU.empty()) {
3068f4a2713aSLionel Sambuc CmdArgs.push_back("-target-cpu");
3069f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(CPU));
3070f4a2713aSLionel Sambuc }
3071f4a2713aSLionel Sambuc
3072f4a2713aSLionel Sambuc if (const Arg *A = Args.getLastArg(options::OPT_mfpmath_EQ)) {
3073f4a2713aSLionel Sambuc CmdArgs.push_back("-mfpmath");
3074f4a2713aSLionel Sambuc CmdArgs.push_back(A->getValue());
3075f4a2713aSLionel Sambuc }
3076f4a2713aSLionel Sambuc
3077f4a2713aSLionel Sambuc // Add the target features
3078*0a6a1f1dSLionel Sambuc getTargetFeatures(D, ETriple, Args, CmdArgs, false);
3079f4a2713aSLionel Sambuc
3080f4a2713aSLionel Sambuc // Add target specific flags.
3081f4a2713aSLionel Sambuc switch(getToolChain().getArch()) {
3082f4a2713aSLionel Sambuc default:
3083f4a2713aSLionel Sambuc break;
3084f4a2713aSLionel Sambuc
3085f4a2713aSLionel Sambuc case llvm::Triple::arm:
3086*0a6a1f1dSLionel Sambuc case llvm::Triple::armeb:
3087f4a2713aSLionel Sambuc case llvm::Triple::thumb:
3088*0a6a1f1dSLionel Sambuc case llvm::Triple::thumbeb:
3089f4a2713aSLionel Sambuc AddARMTargetArgs(Args, CmdArgs, KernelOrKext);
3090f4a2713aSLionel Sambuc break;
3091f4a2713aSLionel Sambuc
3092*0a6a1f1dSLionel Sambuc case llvm::Triple::aarch64:
3093*0a6a1f1dSLionel Sambuc case llvm::Triple::aarch64_be:
3094*0a6a1f1dSLionel Sambuc AddAArch64TargetArgs(Args, CmdArgs);
3095*0a6a1f1dSLionel Sambuc break;
3096*0a6a1f1dSLionel Sambuc
3097f4a2713aSLionel Sambuc case llvm::Triple::mips:
3098f4a2713aSLionel Sambuc case llvm::Triple::mipsel:
3099f4a2713aSLionel Sambuc case llvm::Triple::mips64:
3100f4a2713aSLionel Sambuc case llvm::Triple::mips64el:
3101f4a2713aSLionel Sambuc AddMIPSTargetArgs(Args, CmdArgs);
3102f4a2713aSLionel Sambuc break;
3103f4a2713aSLionel Sambuc
3104*0a6a1f1dSLionel Sambuc case llvm::Triple::ppc:
3105*0a6a1f1dSLionel Sambuc case llvm::Triple::ppc64:
3106*0a6a1f1dSLionel Sambuc case llvm::Triple::ppc64le:
3107*0a6a1f1dSLionel Sambuc AddPPCTargetArgs(Args, CmdArgs);
3108*0a6a1f1dSLionel Sambuc break;
3109*0a6a1f1dSLionel Sambuc
3110f4a2713aSLionel Sambuc case llvm::Triple::sparc:
3111*0a6a1f1dSLionel Sambuc case llvm::Triple::sparcv9:
3112f4a2713aSLionel Sambuc AddSparcTargetArgs(Args, CmdArgs);
3113f4a2713aSLionel Sambuc break;
3114f4a2713aSLionel Sambuc
3115f4a2713aSLionel Sambuc case llvm::Triple::x86:
3116f4a2713aSLionel Sambuc case llvm::Triple::x86_64:
3117f4a2713aSLionel Sambuc AddX86TargetArgs(Args, CmdArgs);
3118f4a2713aSLionel Sambuc break;
3119f4a2713aSLionel Sambuc
3120f4a2713aSLionel Sambuc case llvm::Triple::hexagon:
3121f4a2713aSLionel Sambuc AddHexagonTargetArgs(Args, CmdArgs);
3122f4a2713aSLionel Sambuc break;
3123f4a2713aSLionel Sambuc }
3124f4a2713aSLionel Sambuc
3125f4a2713aSLionel Sambuc // Add clang-cl arguments.
3126f4a2713aSLionel Sambuc if (getToolChain().getDriver().IsCLMode())
3127f4a2713aSLionel Sambuc AddClangCLArgs(Args, CmdArgs);
3128f4a2713aSLionel Sambuc
3129f4a2713aSLionel Sambuc // Pass the linker version in use.
3130f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ)) {
3131f4a2713aSLionel Sambuc CmdArgs.push_back("-target-linker-version");
3132f4a2713aSLionel Sambuc CmdArgs.push_back(A->getValue());
3133f4a2713aSLionel Sambuc }
3134f4a2713aSLionel Sambuc
3135f4a2713aSLionel Sambuc if (!shouldUseLeafFramePointer(Args, getToolChain().getTriple()))
3136f4a2713aSLionel Sambuc CmdArgs.push_back("-momit-leaf-frame-pointer");
3137f4a2713aSLionel Sambuc
3138f4a2713aSLionel Sambuc // Explicitly error on some things we know we don't support and can't just
3139f4a2713aSLionel Sambuc // ignore.
3140f4a2713aSLionel Sambuc types::ID InputType = Inputs[0].getType();
3141f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_fallow_unsupported)) {
3142f4a2713aSLionel Sambuc Arg *Unsupported;
3143f4a2713aSLionel Sambuc if (types::isCXX(InputType) &&
3144f4a2713aSLionel Sambuc getToolChain().getTriple().isOSDarwin() &&
3145f4a2713aSLionel Sambuc getToolChain().getArch() == llvm::Triple::x86) {
3146f4a2713aSLionel Sambuc if ((Unsupported = Args.getLastArg(options::OPT_fapple_kext)) ||
3147f4a2713aSLionel Sambuc (Unsupported = Args.getLastArg(options::OPT_mkernel)))
3148f4a2713aSLionel Sambuc D.Diag(diag::err_drv_clang_unsupported_opt_cxx_darwin_i386)
3149f4a2713aSLionel Sambuc << Unsupported->getOption().getName();
3150f4a2713aSLionel Sambuc }
3151f4a2713aSLionel Sambuc }
3152f4a2713aSLionel Sambuc
3153f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_v);
3154f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_H);
3155f4a2713aSLionel Sambuc if (D.CCPrintHeaders && !D.CCGenDiagnostics) {
3156f4a2713aSLionel Sambuc CmdArgs.push_back("-header-include-file");
3157f4a2713aSLionel Sambuc CmdArgs.push_back(D.CCPrintHeadersFilename ?
3158f4a2713aSLionel Sambuc D.CCPrintHeadersFilename : "-");
3159f4a2713aSLionel Sambuc }
3160f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_P);
3161f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_print_ivar_layout);
3162f4a2713aSLionel Sambuc
3163f4a2713aSLionel Sambuc if (D.CCLogDiagnostics && !D.CCGenDiagnostics) {
3164f4a2713aSLionel Sambuc CmdArgs.push_back("-diagnostic-log-file");
3165f4a2713aSLionel Sambuc CmdArgs.push_back(D.CCLogDiagnosticsFilename ?
3166f4a2713aSLionel Sambuc D.CCLogDiagnosticsFilename : "-");
3167f4a2713aSLionel Sambuc }
3168f4a2713aSLionel Sambuc
3169*0a6a1f1dSLionel Sambuc // Use the last option from "-g" group. "-gline-tables-only" and "-gdwarf-x"
3170*0a6a1f1dSLionel Sambuc // are preserved, all other debug options are substituted with "-g".
3171f4a2713aSLionel Sambuc Args.ClaimAllArgs(options::OPT_g_Group);
3172f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_g_Group)) {
3173*0a6a1f1dSLionel Sambuc if (A->getOption().matches(options::OPT_gline_tables_only) ||
3174*0a6a1f1dSLionel Sambuc A->getOption().matches(options::OPT_g1)) {
3175*0a6a1f1dSLionel Sambuc // FIXME: we should support specifying dwarf version with
3176*0a6a1f1dSLionel Sambuc // -gline-tables-only.
3177f4a2713aSLionel Sambuc CmdArgs.push_back("-gline-tables-only");
3178*0a6a1f1dSLionel Sambuc // Default is dwarf-2 for Darwin, OpenBSD, FreeBSD and Solaris.
3179*0a6a1f1dSLionel Sambuc const llvm::Triple &Triple = getToolChain().getTriple();
3180*0a6a1f1dSLionel Sambuc if (Triple.isOSDarwin() || Triple.getOS() == llvm::Triple::OpenBSD ||
3181*0a6a1f1dSLionel Sambuc Triple.getOS() == llvm::Triple::FreeBSD ||
3182*0a6a1f1dSLionel Sambuc Triple.getOS() == llvm::Triple::Solaris)
3183*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-gdwarf-2");
3184*0a6a1f1dSLionel Sambuc } else if (A->getOption().matches(options::OPT_gdwarf_2))
3185f4a2713aSLionel Sambuc CmdArgs.push_back("-gdwarf-2");
3186f4a2713aSLionel Sambuc else if (A->getOption().matches(options::OPT_gdwarf_3))
3187f4a2713aSLionel Sambuc CmdArgs.push_back("-gdwarf-3");
3188f4a2713aSLionel Sambuc else if (A->getOption().matches(options::OPT_gdwarf_4))
3189f4a2713aSLionel Sambuc CmdArgs.push_back("-gdwarf-4");
3190f4a2713aSLionel Sambuc else if (!A->getOption().matches(options::OPT_g0) &&
3191f4a2713aSLionel Sambuc !A->getOption().matches(options::OPT_ggdb0)) {
3192*0a6a1f1dSLionel Sambuc // Default is dwarf-2 for Darwin, OpenBSD, FreeBSD and Solaris.
3193*0a6a1f1dSLionel Sambuc const llvm::Triple &Triple = getToolChain().getTriple();
3194*0a6a1f1dSLionel Sambuc if (Triple.isOSDarwin() || Triple.getOS() == llvm::Triple::OpenBSD ||
3195*0a6a1f1dSLionel Sambuc Triple.getOS() == llvm::Triple::FreeBSD ||
3196*0a6a1f1dSLionel Sambuc Triple.getOS() == llvm::Triple::Solaris)
3197f4a2713aSLionel Sambuc CmdArgs.push_back("-gdwarf-2");
3198f4a2713aSLionel Sambuc else
3199f4a2713aSLionel Sambuc CmdArgs.push_back("-g");
3200f4a2713aSLionel Sambuc }
3201f4a2713aSLionel Sambuc }
3202f4a2713aSLionel Sambuc
3203f4a2713aSLionel Sambuc // We ignore flags -gstrict-dwarf and -grecord-gcc-switches for now.
3204f4a2713aSLionel Sambuc Args.ClaimAllArgs(options::OPT_g_flags_Group);
3205*0a6a1f1dSLionel Sambuc if (Args.hasFlag(options::OPT_gcolumn_info, options::OPT_gno_column_info,
3206*0a6a1f1dSLionel Sambuc /*Default*/ true))
3207f4a2713aSLionel Sambuc CmdArgs.push_back("-dwarf-column-info");
3208f4a2713aSLionel Sambuc
3209f4a2713aSLionel Sambuc // FIXME: Move backend command line options to the module.
3210f4a2713aSLionel Sambuc // -gsplit-dwarf should turn on -g and enable the backend dwarf
3211f4a2713aSLionel Sambuc // splitting and extraction.
3212f4a2713aSLionel Sambuc // FIXME: Currently only works on Linux.
3213f4a2713aSLionel Sambuc if (getToolChain().getTriple().isOSLinux() &&
3214f4a2713aSLionel Sambuc Args.hasArg(options::OPT_gsplit_dwarf)) {
3215f4a2713aSLionel Sambuc CmdArgs.push_back("-g");
3216f4a2713aSLionel Sambuc CmdArgs.push_back("-backend-option");
3217f4a2713aSLionel Sambuc CmdArgs.push_back("-split-dwarf=Enable");
3218f4a2713aSLionel Sambuc }
3219f4a2713aSLionel Sambuc
3220f4a2713aSLionel Sambuc // -ggnu-pubnames turns on gnu style pubnames in the backend.
3221f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_ggnu_pubnames)) {
3222f4a2713aSLionel Sambuc CmdArgs.push_back("-backend-option");
3223f4a2713aSLionel Sambuc CmdArgs.push_back("-generate-gnu-dwarf-pub-sections");
3224f4a2713aSLionel Sambuc }
3225f4a2713aSLionel Sambuc
3226*0a6a1f1dSLionel Sambuc // -gdwarf-aranges turns on the emission of the aranges section in the
3227*0a6a1f1dSLionel Sambuc // backend.
3228*0a6a1f1dSLionel Sambuc if (Args.hasArg(options::OPT_gdwarf_aranges)) {
3229*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-backend-option");
3230*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-generate-arange-section");
3231*0a6a1f1dSLionel Sambuc }
3232f4a2713aSLionel Sambuc
3233*0a6a1f1dSLionel Sambuc if (Args.hasFlag(options::OPT_fdebug_types_section,
3234*0a6a1f1dSLionel Sambuc options::OPT_fno_debug_types_section, false)) {
3235*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-backend-option");
3236*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-generate-type-units");
3237*0a6a1f1dSLionel Sambuc }
3238*0a6a1f1dSLionel Sambuc
3239*0a6a1f1dSLionel Sambuc if (Args.hasFlag(options::OPT_ffunction_sections,
3240*0a6a1f1dSLionel Sambuc options::OPT_fno_function_sections, false)) {
3241*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-ffunction-sections");
3242*0a6a1f1dSLionel Sambuc }
3243*0a6a1f1dSLionel Sambuc
3244*0a6a1f1dSLionel Sambuc if (Args.hasFlag(options::OPT_fdata_sections,
3245*0a6a1f1dSLionel Sambuc options::OPT_fno_data_sections, false)) {
3246*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-fdata-sections");
3247*0a6a1f1dSLionel Sambuc }
3248f4a2713aSLionel Sambuc
3249f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_finstrument_functions);
3250f4a2713aSLionel Sambuc
3251*0a6a1f1dSLionel Sambuc if (Args.hasArg(options::OPT_fprofile_instr_generate) &&
3252*0a6a1f1dSLionel Sambuc (Args.hasArg(options::OPT_fprofile_instr_use) ||
3253*0a6a1f1dSLionel Sambuc Args.hasArg(options::OPT_fprofile_instr_use_EQ)))
3254*0a6a1f1dSLionel Sambuc D.Diag(diag::err_drv_argument_not_allowed_with)
3255*0a6a1f1dSLionel Sambuc << "-fprofile-instr-generate" << "-fprofile-instr-use";
3256*0a6a1f1dSLionel Sambuc
3257*0a6a1f1dSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_fprofile_instr_generate);
3258*0a6a1f1dSLionel Sambuc
3259*0a6a1f1dSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_fprofile_instr_use_EQ))
3260*0a6a1f1dSLionel Sambuc A->render(Args, CmdArgs);
3261*0a6a1f1dSLionel Sambuc else if (Args.hasArg(options::OPT_fprofile_instr_use))
3262*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-fprofile-instr-use=pgo-data");
3263*0a6a1f1dSLionel Sambuc
3264f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_ftest_coverage) ||
3265f4a2713aSLionel Sambuc Args.hasArg(options::OPT_coverage))
3266f4a2713aSLionel Sambuc CmdArgs.push_back("-femit-coverage-notes");
3267*0a6a1f1dSLionel Sambuc if (Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs,
3268*0a6a1f1dSLionel Sambuc false) ||
3269f4a2713aSLionel Sambuc Args.hasArg(options::OPT_coverage))
3270f4a2713aSLionel Sambuc CmdArgs.push_back("-femit-coverage-data");
3271f4a2713aSLionel Sambuc
3272*0a6a1f1dSLionel Sambuc if (Args.hasArg(options::OPT_fcoverage_mapping) &&
3273*0a6a1f1dSLionel Sambuc !Args.hasArg(options::OPT_fprofile_instr_generate))
3274*0a6a1f1dSLionel Sambuc D.Diag(diag::err_drv_argument_only_allowed_with)
3275*0a6a1f1dSLionel Sambuc << "-fcoverage-mapping" << "-fprofile-instr-generate";
3276*0a6a1f1dSLionel Sambuc
3277*0a6a1f1dSLionel Sambuc if (Args.hasArg(options::OPT_fcoverage_mapping))
3278*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-fcoverage-mapping");
3279*0a6a1f1dSLionel Sambuc
3280f4a2713aSLionel Sambuc if (C.getArgs().hasArg(options::OPT_c) ||
3281f4a2713aSLionel Sambuc C.getArgs().hasArg(options::OPT_S)) {
3282f4a2713aSLionel Sambuc if (Output.isFilename()) {
3283f4a2713aSLionel Sambuc CmdArgs.push_back("-coverage-file");
3284*0a6a1f1dSLionel Sambuc SmallString<128> CoverageFilename;
3285*0a6a1f1dSLionel Sambuc if (Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o)) {
3286*0a6a1f1dSLionel Sambuc CoverageFilename = FinalOutput->getValue();
3287*0a6a1f1dSLionel Sambuc } else {
3288*0a6a1f1dSLionel Sambuc CoverageFilename = llvm::sys::path::filename(Output.getBaseInput());
3289*0a6a1f1dSLionel Sambuc }
3290f4a2713aSLionel Sambuc if (llvm::sys::path::is_relative(CoverageFilename.str())) {
3291f4a2713aSLionel Sambuc SmallString<128> Pwd;
3292f4a2713aSLionel Sambuc if (!llvm::sys::fs::current_path(Pwd)) {
3293f4a2713aSLionel Sambuc llvm::sys::path::append(Pwd, CoverageFilename.str());
3294f4a2713aSLionel Sambuc CoverageFilename.swap(Pwd);
3295f4a2713aSLionel Sambuc }
3296f4a2713aSLionel Sambuc }
3297f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(CoverageFilename));
3298f4a2713aSLionel Sambuc }
3299f4a2713aSLionel Sambuc }
3300f4a2713aSLionel Sambuc
3301f4a2713aSLionel Sambuc // Pass options for controlling the default header search paths.
3302f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_nostdinc)) {
3303f4a2713aSLionel Sambuc CmdArgs.push_back("-nostdsysteminc");
3304f4a2713aSLionel Sambuc CmdArgs.push_back("-nobuiltininc");
3305f4a2713aSLionel Sambuc } else {
3306f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_nostdlibinc))
3307f4a2713aSLionel Sambuc CmdArgs.push_back("-nostdsysteminc");
3308f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_nostdincxx);
3309f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_nobuiltininc);
3310f4a2713aSLionel Sambuc }
3311f4a2713aSLionel Sambuc
3312f4a2713aSLionel Sambuc // Pass the path to compiler resource files.
3313f4a2713aSLionel Sambuc CmdArgs.push_back("-resource-dir");
3314f4a2713aSLionel Sambuc CmdArgs.push_back(D.ResourceDir.c_str());
3315f4a2713aSLionel Sambuc
3316f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_working_directory);
3317f4a2713aSLionel Sambuc
3318f4a2713aSLionel Sambuc bool ARCMTEnabled = false;
3319f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_fno_objc_arc, options::OPT_fobjc_arc)) {
3320f4a2713aSLionel Sambuc if (const Arg *A = Args.getLastArg(options::OPT_ccc_arcmt_check,
3321f4a2713aSLionel Sambuc options::OPT_ccc_arcmt_modify,
3322f4a2713aSLionel Sambuc options::OPT_ccc_arcmt_migrate)) {
3323f4a2713aSLionel Sambuc ARCMTEnabled = true;
3324f4a2713aSLionel Sambuc switch (A->getOption().getID()) {
3325f4a2713aSLionel Sambuc default:
3326f4a2713aSLionel Sambuc llvm_unreachable("missed a case");
3327f4a2713aSLionel Sambuc case options::OPT_ccc_arcmt_check:
3328f4a2713aSLionel Sambuc CmdArgs.push_back("-arcmt-check");
3329f4a2713aSLionel Sambuc break;
3330f4a2713aSLionel Sambuc case options::OPT_ccc_arcmt_modify:
3331f4a2713aSLionel Sambuc CmdArgs.push_back("-arcmt-modify");
3332f4a2713aSLionel Sambuc break;
3333f4a2713aSLionel Sambuc case options::OPT_ccc_arcmt_migrate:
3334f4a2713aSLionel Sambuc CmdArgs.push_back("-arcmt-migrate");
3335f4a2713aSLionel Sambuc CmdArgs.push_back("-mt-migrate-directory");
3336f4a2713aSLionel Sambuc CmdArgs.push_back(A->getValue());
3337f4a2713aSLionel Sambuc
3338f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_arcmt_migrate_report_output);
3339f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_arcmt_migrate_emit_arc_errors);
3340f4a2713aSLionel Sambuc break;
3341f4a2713aSLionel Sambuc }
3342f4a2713aSLionel Sambuc }
3343f4a2713aSLionel Sambuc } else {
3344f4a2713aSLionel Sambuc Args.ClaimAllArgs(options::OPT_ccc_arcmt_check);
3345f4a2713aSLionel Sambuc Args.ClaimAllArgs(options::OPT_ccc_arcmt_modify);
3346f4a2713aSLionel Sambuc Args.ClaimAllArgs(options::OPT_ccc_arcmt_migrate);
3347f4a2713aSLionel Sambuc }
3348f4a2713aSLionel Sambuc
3349f4a2713aSLionel Sambuc if (const Arg *A = Args.getLastArg(options::OPT_ccc_objcmt_migrate)) {
3350f4a2713aSLionel Sambuc if (ARCMTEnabled) {
3351f4a2713aSLionel Sambuc D.Diag(diag::err_drv_argument_not_allowed_with)
3352f4a2713aSLionel Sambuc << A->getAsString(Args) << "-ccc-arcmt-migrate";
3353f4a2713aSLionel Sambuc }
3354f4a2713aSLionel Sambuc CmdArgs.push_back("-mt-migrate-directory");
3355f4a2713aSLionel Sambuc CmdArgs.push_back(A->getValue());
3356f4a2713aSLionel Sambuc
3357f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_objcmt_migrate_literals,
3358f4a2713aSLionel Sambuc options::OPT_objcmt_migrate_subscripting,
3359f4a2713aSLionel Sambuc options::OPT_objcmt_migrate_property)) {
3360f4a2713aSLionel Sambuc // None specified, means enable them all.
3361f4a2713aSLionel Sambuc CmdArgs.push_back("-objcmt-migrate-literals");
3362f4a2713aSLionel Sambuc CmdArgs.push_back("-objcmt-migrate-subscripting");
3363f4a2713aSLionel Sambuc CmdArgs.push_back("-objcmt-migrate-property");
3364f4a2713aSLionel Sambuc } else {
3365f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_literals);
3366f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_subscripting);
3367f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_property);
3368f4a2713aSLionel Sambuc }
3369f4a2713aSLionel Sambuc } else {
3370f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_literals);
3371f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_subscripting);
3372f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_property);
3373f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_all);
3374f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_readonly_property);
3375f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_readwrite_property);
3376f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_annotation);
3377f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_instancetype);
3378f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_nsmacros);
3379f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_protocol_conformance);
3380f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_objcmt_atomic_property);
3381f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_objcmt_returns_innerpointer_property);
3382f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_objcmt_ns_nonatomic_iosonly);
3383*0a6a1f1dSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_designated_init);
3384*0a6a1f1dSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_objcmt_whitelist_dir_path);
3385f4a2713aSLionel Sambuc }
3386f4a2713aSLionel Sambuc
3387f4a2713aSLionel Sambuc // Add preprocessing options like -I, -D, etc. if we are using the
3388f4a2713aSLionel Sambuc // preprocessor.
3389f4a2713aSLionel Sambuc //
3390f4a2713aSLionel Sambuc // FIXME: Support -fpreprocessed
3391f4a2713aSLionel Sambuc if (types::getPreprocessedType(InputType) != types::TY_INVALID)
3392f4a2713aSLionel Sambuc AddPreprocessingOptions(C, JA, D, Args, CmdArgs, Output, Inputs);
3393f4a2713aSLionel Sambuc
3394f4a2713aSLionel Sambuc // Don't warn about "clang -c -DPIC -fPIC test.i" because libtool.m4 assumes
3395f4a2713aSLionel Sambuc // that "The compiler can only warn and ignore the option if not recognized".
3396f4a2713aSLionel Sambuc // When building with ccache, it will pass -D options to clang even on
3397f4a2713aSLionel Sambuc // preprocessed inputs and configure concludes that -fPIC is not supported.
3398f4a2713aSLionel Sambuc Args.ClaimAllArgs(options::OPT_D);
3399f4a2713aSLionel Sambuc
3400f4a2713aSLionel Sambuc // Manually translate -O4 to -O3; let clang reject others.
3401f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
3402f4a2713aSLionel Sambuc if (A->getOption().matches(options::OPT_O4)) {
3403f4a2713aSLionel Sambuc CmdArgs.push_back("-O3");
3404f4a2713aSLionel Sambuc D.Diag(diag::warn_O4_is_O3);
3405f4a2713aSLionel Sambuc } else {
3406f4a2713aSLionel Sambuc A->render(Args, CmdArgs);
3407f4a2713aSLionel Sambuc }
3408f4a2713aSLionel Sambuc }
3409f4a2713aSLionel Sambuc
3410*0a6a1f1dSLionel Sambuc // Warn about ignored options to clang.
3411*0a6a1f1dSLionel Sambuc for (arg_iterator it = Args.filtered_begin(
3412*0a6a1f1dSLionel Sambuc options::OPT_clang_ignored_gcc_optimization_f_Group),
3413*0a6a1f1dSLionel Sambuc ie = Args.filtered_end(); it != ie; ++it) {
3414*0a6a1f1dSLionel Sambuc D.Diag(diag::warn_ignored_gcc_optimization) << (*it)->getAsString(Args);
3415*0a6a1f1dSLionel Sambuc }
3416f4a2713aSLionel Sambuc
3417*0a6a1f1dSLionel Sambuc claimNoWarnArgs(Args);
3418*0a6a1f1dSLionel Sambuc
3419*0a6a1f1dSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_R_Group);
3420f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_W_Group);
3421f4a2713aSLionel Sambuc if (Args.hasFlag(options::OPT_pedantic, options::OPT_no_pedantic, false))
3422f4a2713aSLionel Sambuc CmdArgs.push_back("-pedantic");
3423f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_pedantic_errors);
3424f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_w);
3425f4a2713aSLionel Sambuc
3426f4a2713aSLionel Sambuc // Handle -{std, ansi, trigraphs} -- take the last of -{std, ansi}
3427f4a2713aSLionel Sambuc // (-ansi is equivalent to -std=c89 or -std=c++98).
3428f4a2713aSLionel Sambuc //
3429f4a2713aSLionel Sambuc // If a std is supplied, only add -trigraphs if it follows the
3430f4a2713aSLionel Sambuc // option.
3431f4a2713aSLionel Sambuc if (Arg *Std = Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi)) {
3432f4a2713aSLionel Sambuc if (Std->getOption().matches(options::OPT_ansi))
3433f4a2713aSLionel Sambuc if (types::isCXX(InputType))
3434f4a2713aSLionel Sambuc CmdArgs.push_back("-std=c++98");
3435f4a2713aSLionel Sambuc else
3436f4a2713aSLionel Sambuc CmdArgs.push_back("-std=c89");
3437f4a2713aSLionel Sambuc else
3438f4a2713aSLionel Sambuc Std->render(Args, CmdArgs);
3439f4a2713aSLionel Sambuc
3440*0a6a1f1dSLionel Sambuc // If -f(no-)trigraphs appears after the language standard flag, honor it.
3441f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi,
3442*0a6a1f1dSLionel Sambuc options::OPT_ftrigraphs,
3443*0a6a1f1dSLionel Sambuc options::OPT_fno_trigraphs))
3444f4a2713aSLionel Sambuc if (A != Std)
3445f4a2713aSLionel Sambuc A->render(Args, CmdArgs);
3446f4a2713aSLionel Sambuc } else {
3447f4a2713aSLionel Sambuc // Honor -std-default.
3448f4a2713aSLionel Sambuc //
3449f4a2713aSLionel Sambuc // FIXME: Clang doesn't correctly handle -std= when the input language
3450f4a2713aSLionel Sambuc // doesn't match. For the time being just ignore this for C++ inputs;
3451f4a2713aSLionel Sambuc // eventually we want to do all the standard defaulting here instead of
3452f4a2713aSLionel Sambuc // splitting it between the driver and clang -cc1.
3453f4a2713aSLionel Sambuc if (!types::isCXX(InputType))
3454f4a2713aSLionel Sambuc Args.AddAllArgsTranslated(CmdArgs, options::OPT_std_default_EQ,
3455f4a2713aSLionel Sambuc "-std=", /*Joined=*/true);
3456*0a6a1f1dSLionel Sambuc else if (IsWindowsMSVC)
3457f4a2713aSLionel Sambuc CmdArgs.push_back("-std=c++11");
3458f4a2713aSLionel Sambuc
3459*0a6a1f1dSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_ftrigraphs,
3460*0a6a1f1dSLionel Sambuc options::OPT_fno_trigraphs);
3461f4a2713aSLionel Sambuc }
3462f4a2713aSLionel Sambuc
3463f4a2713aSLionel Sambuc // GCC's behavior for -Wwrite-strings is a bit strange:
3464f4a2713aSLionel Sambuc // * In C, this "warning flag" changes the types of string literals from
3465f4a2713aSLionel Sambuc // 'char[N]' to 'const char[N]', and thus triggers an unrelated warning
3466f4a2713aSLionel Sambuc // for the discarded qualifier.
3467f4a2713aSLionel Sambuc // * In C++, this is just a normal warning flag.
3468f4a2713aSLionel Sambuc //
3469f4a2713aSLionel Sambuc // Implementing this warning correctly in C is hard, so we follow GCC's
3470f4a2713aSLionel Sambuc // behavior for now. FIXME: Directly diagnose uses of a string literal as
3471f4a2713aSLionel Sambuc // a non-const char* in C, rather than using this crude hack.
3472f4a2713aSLionel Sambuc if (!types::isCXX(InputType)) {
3473*0a6a1f1dSLionel Sambuc // FIXME: This should behave just like a warning flag, and thus should also
3474*0a6a1f1dSLionel Sambuc // respect -Weverything, -Wno-everything, -Werror=write-strings, and so on.
3475*0a6a1f1dSLionel Sambuc Arg *WriteStrings =
3476*0a6a1f1dSLionel Sambuc Args.getLastArg(options::OPT_Wwrite_strings,
3477*0a6a1f1dSLionel Sambuc options::OPT_Wno_write_strings, options::OPT_w);
3478*0a6a1f1dSLionel Sambuc if (WriteStrings &&
3479*0a6a1f1dSLionel Sambuc WriteStrings->getOption().matches(options::OPT_Wwrite_strings))
3480f4a2713aSLionel Sambuc CmdArgs.push_back("-fconst-strings");
3481f4a2713aSLionel Sambuc }
3482f4a2713aSLionel Sambuc
3483f4a2713aSLionel Sambuc // GCC provides a macro definition '__DEPRECATED' when -Wdeprecated is active
3484f4a2713aSLionel Sambuc // during C++ compilation, which it is by default. GCC keeps this define even
3485f4a2713aSLionel Sambuc // in the presence of '-w', match this behavior bug-for-bug.
3486f4a2713aSLionel Sambuc if (types::isCXX(InputType) &&
3487f4a2713aSLionel Sambuc Args.hasFlag(options::OPT_Wdeprecated, options::OPT_Wno_deprecated,
3488f4a2713aSLionel Sambuc true)) {
3489f4a2713aSLionel Sambuc CmdArgs.push_back("-fdeprecated-macro");
3490f4a2713aSLionel Sambuc }
3491f4a2713aSLionel Sambuc
3492f4a2713aSLionel Sambuc // Translate GCC's misnamer '-fasm' arguments to '-fgnu-keywords'.
3493f4a2713aSLionel Sambuc if (Arg *Asm = Args.getLastArg(options::OPT_fasm, options::OPT_fno_asm)) {
3494f4a2713aSLionel Sambuc if (Asm->getOption().matches(options::OPT_fasm))
3495f4a2713aSLionel Sambuc CmdArgs.push_back("-fgnu-keywords");
3496f4a2713aSLionel Sambuc else
3497f4a2713aSLionel Sambuc CmdArgs.push_back("-fno-gnu-keywords");
3498f4a2713aSLionel Sambuc }
3499f4a2713aSLionel Sambuc
3500f4a2713aSLionel Sambuc if (ShouldDisableDwarfDirectory(Args, getToolChain()))
3501f4a2713aSLionel Sambuc CmdArgs.push_back("-fno-dwarf-directory-asm");
3502f4a2713aSLionel Sambuc
3503f4a2713aSLionel Sambuc if (ShouldDisableAutolink(Args, getToolChain()))
3504f4a2713aSLionel Sambuc CmdArgs.push_back("-fno-autolink");
3505f4a2713aSLionel Sambuc
3506f4a2713aSLionel Sambuc // Add in -fdebug-compilation-dir if necessary.
3507f4a2713aSLionel Sambuc addDebugCompDirArg(Args, CmdArgs);
3508f4a2713aSLionel Sambuc
3509f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_ftemplate_depth_,
3510f4a2713aSLionel Sambuc options::OPT_ftemplate_depth_EQ)) {
3511f4a2713aSLionel Sambuc CmdArgs.push_back("-ftemplate-depth");
3512f4a2713aSLionel Sambuc CmdArgs.push_back(A->getValue());
3513f4a2713aSLionel Sambuc }
3514f4a2713aSLionel Sambuc
3515f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_foperator_arrow_depth_EQ)) {
3516f4a2713aSLionel Sambuc CmdArgs.push_back("-foperator-arrow-depth");
3517f4a2713aSLionel Sambuc CmdArgs.push_back(A->getValue());
3518f4a2713aSLionel Sambuc }
3519f4a2713aSLionel Sambuc
3520f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_fconstexpr_depth_EQ)) {
3521f4a2713aSLionel Sambuc CmdArgs.push_back("-fconstexpr-depth");
3522f4a2713aSLionel Sambuc CmdArgs.push_back(A->getValue());
3523f4a2713aSLionel Sambuc }
3524f4a2713aSLionel Sambuc
3525f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_fconstexpr_steps_EQ)) {
3526f4a2713aSLionel Sambuc CmdArgs.push_back("-fconstexpr-steps");
3527f4a2713aSLionel Sambuc CmdArgs.push_back(A->getValue());
3528f4a2713aSLionel Sambuc }
3529f4a2713aSLionel Sambuc
3530f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_fbracket_depth_EQ)) {
3531f4a2713aSLionel Sambuc CmdArgs.push_back("-fbracket-depth");
3532f4a2713aSLionel Sambuc CmdArgs.push_back(A->getValue());
3533f4a2713aSLionel Sambuc }
3534f4a2713aSLionel Sambuc
3535f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_Wlarge_by_value_copy_EQ,
3536f4a2713aSLionel Sambuc options::OPT_Wlarge_by_value_copy_def)) {
3537f4a2713aSLionel Sambuc if (A->getNumValues()) {
3538f4a2713aSLionel Sambuc StringRef bytes = A->getValue();
3539f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString("-Wlarge-by-value-copy=" + bytes));
3540f4a2713aSLionel Sambuc } else
3541f4a2713aSLionel Sambuc CmdArgs.push_back("-Wlarge-by-value-copy=64"); // default value
3542f4a2713aSLionel Sambuc }
3543f4a2713aSLionel Sambuc
3544f4a2713aSLionel Sambuc
3545f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_relocatable_pch))
3546f4a2713aSLionel Sambuc CmdArgs.push_back("-relocatable-pch");
3547f4a2713aSLionel Sambuc
3548f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_fconstant_string_class_EQ)) {
3549f4a2713aSLionel Sambuc CmdArgs.push_back("-fconstant-string-class");
3550f4a2713aSLionel Sambuc CmdArgs.push_back(A->getValue());
3551f4a2713aSLionel Sambuc }
3552f4a2713aSLionel Sambuc
3553f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_ftabstop_EQ)) {
3554f4a2713aSLionel Sambuc CmdArgs.push_back("-ftabstop");
3555f4a2713aSLionel Sambuc CmdArgs.push_back(A->getValue());
3556f4a2713aSLionel Sambuc }
3557f4a2713aSLionel Sambuc
3558f4a2713aSLionel Sambuc CmdArgs.push_back("-ferror-limit");
3559f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_ferror_limit_EQ))
3560f4a2713aSLionel Sambuc CmdArgs.push_back(A->getValue());
3561f4a2713aSLionel Sambuc else
3562f4a2713aSLionel Sambuc CmdArgs.push_back("19");
3563f4a2713aSLionel Sambuc
3564f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_fmacro_backtrace_limit_EQ)) {
3565f4a2713aSLionel Sambuc CmdArgs.push_back("-fmacro-backtrace-limit");
3566f4a2713aSLionel Sambuc CmdArgs.push_back(A->getValue());
3567f4a2713aSLionel Sambuc }
3568f4a2713aSLionel Sambuc
3569f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_ftemplate_backtrace_limit_EQ)) {
3570f4a2713aSLionel Sambuc CmdArgs.push_back("-ftemplate-backtrace-limit");
3571f4a2713aSLionel Sambuc CmdArgs.push_back(A->getValue());
3572f4a2713aSLionel Sambuc }
3573f4a2713aSLionel Sambuc
3574f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_fconstexpr_backtrace_limit_EQ)) {
3575f4a2713aSLionel Sambuc CmdArgs.push_back("-fconstexpr-backtrace-limit");
3576f4a2713aSLionel Sambuc CmdArgs.push_back(A->getValue());
3577f4a2713aSLionel Sambuc }
3578f4a2713aSLionel Sambuc
3579*0a6a1f1dSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_fspell_checking_limit_EQ)) {
3580*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-fspell-checking-limit");
3581*0a6a1f1dSLionel Sambuc CmdArgs.push_back(A->getValue());
3582*0a6a1f1dSLionel Sambuc }
3583*0a6a1f1dSLionel Sambuc
3584f4a2713aSLionel Sambuc // Pass -fmessage-length=.
3585f4a2713aSLionel Sambuc CmdArgs.push_back("-fmessage-length");
3586f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_fmessage_length_EQ)) {
3587f4a2713aSLionel Sambuc CmdArgs.push_back(A->getValue());
3588f4a2713aSLionel Sambuc } else {
3589f4a2713aSLionel Sambuc // If -fmessage-length=N was not specified, determine whether this is a
3590f4a2713aSLionel Sambuc // terminal and, if so, implicitly define -fmessage-length appropriately.
3591f4a2713aSLionel Sambuc unsigned N = llvm::sys::Process::StandardErrColumns();
3592f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(Twine(N)));
3593f4a2713aSLionel Sambuc }
3594f4a2713aSLionel Sambuc
3595f4a2713aSLionel Sambuc // -fvisibility= and -fvisibility-ms-compat are of a piece.
3596f4a2713aSLionel Sambuc if (const Arg *A = Args.getLastArg(options::OPT_fvisibility_EQ,
3597f4a2713aSLionel Sambuc options::OPT_fvisibility_ms_compat)) {
3598f4a2713aSLionel Sambuc if (A->getOption().matches(options::OPT_fvisibility_EQ)) {
3599f4a2713aSLionel Sambuc CmdArgs.push_back("-fvisibility");
3600f4a2713aSLionel Sambuc CmdArgs.push_back(A->getValue());
3601f4a2713aSLionel Sambuc } else {
3602f4a2713aSLionel Sambuc assert(A->getOption().matches(options::OPT_fvisibility_ms_compat));
3603f4a2713aSLionel Sambuc CmdArgs.push_back("-fvisibility");
3604f4a2713aSLionel Sambuc CmdArgs.push_back("hidden");
3605f4a2713aSLionel Sambuc CmdArgs.push_back("-ftype-visibility");
3606f4a2713aSLionel Sambuc CmdArgs.push_back("default");
3607f4a2713aSLionel Sambuc }
3608f4a2713aSLionel Sambuc }
3609f4a2713aSLionel Sambuc
3610f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_fvisibility_inlines_hidden);
3611f4a2713aSLionel Sambuc
3612f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_ftlsmodel_EQ);
3613f4a2713aSLionel Sambuc
3614f4a2713aSLionel Sambuc // -fhosted is default.
3615f4a2713aSLionel Sambuc if (Args.hasFlag(options::OPT_ffreestanding, options::OPT_fhosted, false) ||
3616f4a2713aSLionel Sambuc KernelOrKext)
3617f4a2713aSLionel Sambuc CmdArgs.push_back("-ffreestanding");
3618f4a2713aSLionel Sambuc
3619f4a2713aSLionel Sambuc // Forward -f (flag) options which we can pass directly.
3620f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_femit_all_decls);
3621f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_fheinous_gnu_extensions);
3622*0a6a1f1dSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_fstandalone_debug);
3623*0a6a1f1dSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_fno_standalone_debug);
3624f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_fno_operator_names);
3625f4a2713aSLionel Sambuc // AltiVec language extensions aren't relevant for assembling.
3626f4a2713aSLionel Sambuc if (!isa<PreprocessJobAction>(JA) ||
3627f4a2713aSLionel Sambuc Output.getType() != types::TY_PP_Asm)
3628f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_faltivec);
3629f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_show_template_tree);
3630f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_fno_elide_type);
3631f4a2713aSLionel Sambuc
3632f4a2713aSLionel Sambuc const SanitizerArgs &Sanitize = getToolChain().getSanitizerArgs();
3633f4a2713aSLionel Sambuc Sanitize.addArgs(Args, CmdArgs);
3634f4a2713aSLionel Sambuc
3635f4a2713aSLionel Sambuc // Report an error for -faltivec on anything other than PowerPC.
3636f4a2713aSLionel Sambuc if (const Arg *A = Args.getLastArg(options::OPT_faltivec))
3637f4a2713aSLionel Sambuc if (!(getToolChain().getArch() == llvm::Triple::ppc ||
3638f4a2713aSLionel Sambuc getToolChain().getArch() == llvm::Triple::ppc64 ||
3639f4a2713aSLionel Sambuc getToolChain().getArch() == llvm::Triple::ppc64le))
3640f4a2713aSLionel Sambuc D.Diag(diag::err_drv_argument_only_allowed_with)
3641f4a2713aSLionel Sambuc << A->getAsString(Args) << "ppc/ppc64/ppc64le";
3642f4a2713aSLionel Sambuc
3643f4a2713aSLionel Sambuc if (getToolChain().SupportsProfiling())
3644f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_pg);
3645f4a2713aSLionel Sambuc
3646f4a2713aSLionel Sambuc // -flax-vector-conversions is default.
3647f4a2713aSLionel Sambuc if (!Args.hasFlag(options::OPT_flax_vector_conversions,
3648f4a2713aSLionel Sambuc options::OPT_fno_lax_vector_conversions))
3649f4a2713aSLionel Sambuc CmdArgs.push_back("-fno-lax-vector-conversions");
3650f4a2713aSLionel Sambuc
3651f4a2713aSLionel Sambuc if (Args.getLastArg(options::OPT_fapple_kext))
3652f4a2713aSLionel Sambuc CmdArgs.push_back("-fapple-kext");
3653f4a2713aSLionel Sambuc
3654f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_fobjc_sender_dependent_dispatch);
3655f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_print_source_range_info);
3656f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_parseable_fixits);
3657f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_ftime_report);
3658f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_ftrapv);
3659f4a2713aSLionel Sambuc
3660f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_ftrapv_handler_EQ)) {
3661f4a2713aSLionel Sambuc CmdArgs.push_back("-ftrapv-handler");
3662f4a2713aSLionel Sambuc CmdArgs.push_back(A->getValue());
3663f4a2713aSLionel Sambuc }
3664f4a2713aSLionel Sambuc
3665f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_ftrap_function_EQ);
3666f4a2713aSLionel Sambuc
3667f4a2713aSLionel Sambuc // -fno-strict-overflow implies -fwrapv if it isn't disabled, but
3668f4a2713aSLionel Sambuc // -fstrict-overflow won't turn off an explicitly enabled -fwrapv.
3669f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_fwrapv,
3670f4a2713aSLionel Sambuc options::OPT_fno_wrapv)) {
3671f4a2713aSLionel Sambuc if (A->getOption().matches(options::OPT_fwrapv))
3672f4a2713aSLionel Sambuc CmdArgs.push_back("-fwrapv");
3673f4a2713aSLionel Sambuc } else if (Arg *A = Args.getLastArg(options::OPT_fstrict_overflow,
3674f4a2713aSLionel Sambuc options::OPT_fno_strict_overflow)) {
3675f4a2713aSLionel Sambuc if (A->getOption().matches(options::OPT_fno_strict_overflow))
3676f4a2713aSLionel Sambuc CmdArgs.push_back("-fwrapv");
3677f4a2713aSLionel Sambuc }
3678f4a2713aSLionel Sambuc
3679f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_freroll_loops,
3680f4a2713aSLionel Sambuc options::OPT_fno_reroll_loops))
3681f4a2713aSLionel Sambuc if (A->getOption().matches(options::OPT_freroll_loops))
3682f4a2713aSLionel Sambuc CmdArgs.push_back("-freroll-loops");
3683f4a2713aSLionel Sambuc
3684f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_fwritable_strings);
3685f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_funroll_loops,
3686f4a2713aSLionel Sambuc options::OPT_fno_unroll_loops);
3687f4a2713aSLionel Sambuc
3688f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_pthread);
3689f4a2713aSLionel Sambuc
3690f4a2713aSLionel Sambuc
3691f4a2713aSLionel Sambuc // -stack-protector=0 is default.
3692f4a2713aSLionel Sambuc unsigned StackProtectorLevel = 0;
3693f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_fno_stack_protector,
3694f4a2713aSLionel Sambuc options::OPT_fstack_protector_all,
3695*0a6a1f1dSLionel Sambuc options::OPT_fstack_protector_strong,
3696f4a2713aSLionel Sambuc options::OPT_fstack_protector)) {
3697*0a6a1f1dSLionel Sambuc if (A->getOption().matches(options::OPT_fstack_protector)) {
3698*0a6a1f1dSLionel Sambuc StackProtectorLevel = std::max<unsigned>(LangOptions::SSPOn,
3699*0a6a1f1dSLionel Sambuc getToolChain().GetDefaultStackProtectorLevel(KernelOrKext));
3700*0a6a1f1dSLionel Sambuc } else if (A->getOption().matches(options::OPT_fstack_protector_strong))
3701*0a6a1f1dSLionel Sambuc StackProtectorLevel = LangOptions::SSPStrong;
3702f4a2713aSLionel Sambuc else if (A->getOption().matches(options::OPT_fstack_protector_all))
3703*0a6a1f1dSLionel Sambuc StackProtectorLevel = LangOptions::SSPReq;
3704f4a2713aSLionel Sambuc } else {
3705f4a2713aSLionel Sambuc StackProtectorLevel =
3706f4a2713aSLionel Sambuc getToolChain().GetDefaultStackProtectorLevel(KernelOrKext);
3707f4a2713aSLionel Sambuc }
3708f4a2713aSLionel Sambuc if (StackProtectorLevel) {
3709f4a2713aSLionel Sambuc CmdArgs.push_back("-stack-protector");
3710f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(Twine(StackProtectorLevel)));
3711f4a2713aSLionel Sambuc }
3712f4a2713aSLionel Sambuc
3713f4a2713aSLionel Sambuc // --param ssp-buffer-size=
3714f4a2713aSLionel Sambuc for (arg_iterator it = Args.filtered_begin(options::OPT__param),
3715f4a2713aSLionel Sambuc ie = Args.filtered_end(); it != ie; ++it) {
3716f4a2713aSLionel Sambuc StringRef Str((*it)->getValue());
3717f4a2713aSLionel Sambuc if (Str.startswith("ssp-buffer-size=")) {
3718f4a2713aSLionel Sambuc if (StackProtectorLevel) {
3719f4a2713aSLionel Sambuc CmdArgs.push_back("-stack-protector-buffer-size");
3720f4a2713aSLionel Sambuc // FIXME: Verify the argument is a valid integer.
3721f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(Str.drop_front(16)));
3722f4a2713aSLionel Sambuc }
3723f4a2713aSLionel Sambuc (*it)->claim();
3724f4a2713aSLionel Sambuc }
3725f4a2713aSLionel Sambuc }
3726f4a2713aSLionel Sambuc
3727f4a2713aSLionel Sambuc // Translate -mstackrealign
3728f4a2713aSLionel Sambuc if (Args.hasFlag(options::OPT_mstackrealign, options::OPT_mno_stackrealign,
3729f4a2713aSLionel Sambuc false)) {
3730f4a2713aSLionel Sambuc CmdArgs.push_back("-backend-option");
3731f4a2713aSLionel Sambuc CmdArgs.push_back("-force-align-stack");
3732f4a2713aSLionel Sambuc }
3733f4a2713aSLionel Sambuc if (!Args.hasFlag(options::OPT_mno_stackrealign, options::OPT_mstackrealign,
3734f4a2713aSLionel Sambuc false)) {
3735f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString("-mstackrealign"));
3736f4a2713aSLionel Sambuc }
3737f4a2713aSLionel Sambuc
3738f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_mstack_alignment)) {
3739f4a2713aSLionel Sambuc StringRef alignment = Args.getLastArgValue(options::OPT_mstack_alignment);
3740f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString("-mstack-alignment=" + alignment));
3741f4a2713aSLionel Sambuc }
3742*0a6a1f1dSLionel Sambuc
3743*0a6a1f1dSLionel Sambuc if (getToolChain().getTriple().getArch() == llvm::Triple::aarch64 ||
3744*0a6a1f1dSLionel Sambuc getToolChain().getTriple().getArch() == llvm::Triple::aarch64_be)
3745*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-fallow-half-arguments-and-returns");
3746f4a2713aSLionel Sambuc
3747f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_mrestrict_it,
3748f4a2713aSLionel Sambuc options::OPT_mno_restrict_it)) {
3749f4a2713aSLionel Sambuc if (A->getOption().matches(options::OPT_mrestrict_it)) {
3750f4a2713aSLionel Sambuc CmdArgs.push_back("-backend-option");
3751f4a2713aSLionel Sambuc CmdArgs.push_back("-arm-restrict-it");
3752f4a2713aSLionel Sambuc } else {
3753f4a2713aSLionel Sambuc CmdArgs.push_back("-backend-option");
3754f4a2713aSLionel Sambuc CmdArgs.push_back("-arm-no-restrict-it");
3755f4a2713aSLionel Sambuc }
3756*0a6a1f1dSLionel Sambuc } else if (TT.isOSWindows() && (TT.getArch() == llvm::Triple::arm ||
3757*0a6a1f1dSLionel Sambuc TT.getArch() == llvm::Triple::thumb)) {
3758*0a6a1f1dSLionel Sambuc // Windows on ARM expects restricted IT blocks
3759*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-backend-option");
3760*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-arm-restrict-it");
3761*0a6a1f1dSLionel Sambuc }
3762*0a6a1f1dSLionel Sambuc
3763*0a6a1f1dSLionel Sambuc if (TT.getArch() == llvm::Triple::arm ||
3764*0a6a1f1dSLionel Sambuc TT.getArch() == llvm::Triple::thumb) {
3765*0a6a1f1dSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_mlong_calls,
3766*0a6a1f1dSLionel Sambuc options::OPT_mno_long_calls)) {
3767*0a6a1f1dSLionel Sambuc if (A->getOption().matches(options::OPT_mlong_calls)) {
3768*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-backend-option");
3769*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-arm-long-calls");
3770*0a6a1f1dSLionel Sambuc }
3771*0a6a1f1dSLionel Sambuc }
3772f4a2713aSLionel Sambuc }
3773f4a2713aSLionel Sambuc
3774f4a2713aSLionel Sambuc // Forward -f options with positive and negative forms; we translate
3775f4a2713aSLionel Sambuc // these by hand.
3776f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_fprofile_sample_use_EQ)) {
3777f4a2713aSLionel Sambuc StringRef fname = A->getValue();
3778f4a2713aSLionel Sambuc if (!llvm::sys::fs::exists(fname))
3779f4a2713aSLionel Sambuc D.Diag(diag::err_drv_no_such_file) << fname;
3780f4a2713aSLionel Sambuc else
3781f4a2713aSLionel Sambuc A->render(Args, CmdArgs);
3782f4a2713aSLionel Sambuc }
3783f4a2713aSLionel Sambuc
3784f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_mkernel)) {
3785f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_fapple_kext) && types::isCXX(InputType))
3786f4a2713aSLionel Sambuc CmdArgs.push_back("-fapple-kext");
3787f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_fbuiltin))
3788f4a2713aSLionel Sambuc CmdArgs.push_back("-fno-builtin");
3789f4a2713aSLionel Sambuc Args.ClaimAllArgs(options::OPT_fno_builtin);
3790f4a2713aSLionel Sambuc }
3791f4a2713aSLionel Sambuc // -fbuiltin is default.
3792f4a2713aSLionel Sambuc else if (!Args.hasFlag(options::OPT_fbuiltin, options::OPT_fno_builtin))
3793f4a2713aSLionel Sambuc CmdArgs.push_back("-fno-builtin");
3794f4a2713aSLionel Sambuc
3795f4a2713aSLionel Sambuc if (!Args.hasFlag(options::OPT_fassume_sane_operator_new,
3796f4a2713aSLionel Sambuc options::OPT_fno_assume_sane_operator_new))
3797f4a2713aSLionel Sambuc CmdArgs.push_back("-fno-assume-sane-operator-new");
3798f4a2713aSLionel Sambuc
3799f4a2713aSLionel Sambuc // -fblocks=0 is default.
3800f4a2713aSLionel Sambuc if (Args.hasFlag(options::OPT_fblocks, options::OPT_fno_blocks,
3801f4a2713aSLionel Sambuc getToolChain().IsBlocksDefault()) ||
3802f4a2713aSLionel Sambuc (Args.hasArg(options::OPT_fgnu_runtime) &&
3803f4a2713aSLionel Sambuc Args.hasArg(options::OPT_fobjc_nonfragile_abi) &&
3804f4a2713aSLionel Sambuc !Args.hasArg(options::OPT_fno_blocks))) {
3805f4a2713aSLionel Sambuc CmdArgs.push_back("-fblocks");
3806f4a2713aSLionel Sambuc
3807f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_fgnu_runtime) &&
3808f4a2713aSLionel Sambuc !getToolChain().hasBlocksRuntime())
3809f4a2713aSLionel Sambuc CmdArgs.push_back("-fblocks-runtime-optional");
3810f4a2713aSLionel Sambuc }
3811f4a2713aSLionel Sambuc
3812*0a6a1f1dSLionel Sambuc // -fmodules enables modules (off by default).
3813*0a6a1f1dSLionel Sambuc // Users can pass -fno-cxx-modules to turn off modules support for
3814*0a6a1f1dSLionel Sambuc // C++/Objective-C++ programs, which is a little less mature.
3815f4a2713aSLionel Sambuc bool HaveModules = false;
3816f4a2713aSLionel Sambuc if (Args.hasFlag(options::OPT_fmodules, options::OPT_fno_modules, false)) {
3817f4a2713aSLionel Sambuc bool AllowedInCXX = Args.hasFlag(options::OPT_fcxx_modules,
3818f4a2713aSLionel Sambuc options::OPT_fno_cxx_modules,
3819*0a6a1f1dSLionel Sambuc true);
3820f4a2713aSLionel Sambuc if (AllowedInCXX || !types::isCXX(InputType)) {
3821f4a2713aSLionel Sambuc CmdArgs.push_back("-fmodules");
3822f4a2713aSLionel Sambuc HaveModules = true;
3823f4a2713aSLionel Sambuc }
3824f4a2713aSLionel Sambuc }
3825f4a2713aSLionel Sambuc
3826f4a2713aSLionel Sambuc // -fmodule-maps enables module map processing (off by default) for header
3827f4a2713aSLionel Sambuc // checking. It is implied by -fmodules.
3828f4a2713aSLionel Sambuc if (Args.hasFlag(options::OPT_fmodule_maps, options::OPT_fno_module_maps,
3829f4a2713aSLionel Sambuc false)) {
3830f4a2713aSLionel Sambuc CmdArgs.push_back("-fmodule-maps");
3831f4a2713aSLionel Sambuc }
3832f4a2713aSLionel Sambuc
3833f4a2713aSLionel Sambuc // -fmodules-decluse checks that modules used are declared so (off by
3834f4a2713aSLionel Sambuc // default).
3835f4a2713aSLionel Sambuc if (Args.hasFlag(options::OPT_fmodules_decluse,
3836f4a2713aSLionel Sambuc options::OPT_fno_modules_decluse,
3837f4a2713aSLionel Sambuc false)) {
3838f4a2713aSLionel Sambuc CmdArgs.push_back("-fmodules-decluse");
3839f4a2713aSLionel Sambuc }
3840f4a2713aSLionel Sambuc
3841*0a6a1f1dSLionel Sambuc // -fmodules-strict-decluse is like -fmodule-decluse, but also checks that
3842*0a6a1f1dSLionel Sambuc // all #included headers are part of modules.
3843*0a6a1f1dSLionel Sambuc if (Args.hasFlag(options::OPT_fmodules_strict_decluse,
3844*0a6a1f1dSLionel Sambuc options::OPT_fno_modules_strict_decluse,
3845*0a6a1f1dSLionel Sambuc false)) {
3846*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-fmodules-strict-decluse");
3847*0a6a1f1dSLionel Sambuc }
3848*0a6a1f1dSLionel Sambuc
3849f4a2713aSLionel Sambuc // -fmodule-name specifies the module that is currently being built (or
3850f4a2713aSLionel Sambuc // used for header checking by -fmodule-maps).
3851*0a6a1f1dSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_fmodule_name);
3852f4a2713aSLionel Sambuc
3853*0a6a1f1dSLionel Sambuc // -fmodule-map-file can be used to specify files containing module
3854f4a2713aSLionel Sambuc // definitions.
3855*0a6a1f1dSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_fmodule_map_file);
3856*0a6a1f1dSLionel Sambuc
3857*0a6a1f1dSLionel Sambuc // -fmodule-file can be used to specify files containing precompiled modules.
3858*0a6a1f1dSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_fmodule_file);
3859*0a6a1f1dSLionel Sambuc
3860*0a6a1f1dSLionel Sambuc // -fmodule-cache-path specifies where our implicitly-built module files
3861*0a6a1f1dSLionel Sambuc // should be written.
3862*0a6a1f1dSLionel Sambuc SmallString<128> ModuleCachePath;
3863*0a6a1f1dSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_fmodules_cache_path))
3864*0a6a1f1dSLionel Sambuc ModuleCachePath = A->getValue();
3865*0a6a1f1dSLionel Sambuc if (HaveModules) {
3866*0a6a1f1dSLionel Sambuc if (C.isForDiagnostics()) {
3867*0a6a1f1dSLionel Sambuc // When generating crash reports, we want to emit the modules along with
3868*0a6a1f1dSLionel Sambuc // the reproduction sources, so we ignore any provided module path.
3869*0a6a1f1dSLionel Sambuc ModuleCachePath = Output.getFilename();
3870*0a6a1f1dSLionel Sambuc llvm::sys::path::replace_extension(ModuleCachePath, ".cache");
3871*0a6a1f1dSLionel Sambuc llvm::sys::path::append(ModuleCachePath, "modules");
3872*0a6a1f1dSLionel Sambuc } else if (ModuleCachePath.empty()) {
3873*0a6a1f1dSLionel Sambuc // No module path was provided: use the default.
3874*0a6a1f1dSLionel Sambuc llvm::sys::path::system_temp_directory(/*erasedOnReboot=*/false,
3875*0a6a1f1dSLionel Sambuc ModuleCachePath);
3876*0a6a1f1dSLionel Sambuc llvm::sys::path::append(ModuleCachePath, "org.llvm.clang");
3877*0a6a1f1dSLionel Sambuc llvm::sys::path::append(ModuleCachePath, "ModuleCache");
3878*0a6a1f1dSLionel Sambuc }
3879*0a6a1f1dSLionel Sambuc const char Arg[] = "-fmodules-cache-path=";
3880*0a6a1f1dSLionel Sambuc ModuleCachePath.insert(ModuleCachePath.begin(), Arg, Arg + strlen(Arg));
3881*0a6a1f1dSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(ModuleCachePath));
3882f4a2713aSLionel Sambuc }
3883f4a2713aSLionel Sambuc
3884*0a6a1f1dSLionel Sambuc // When building modules and generating crashdumps, we need to dump a module
3885*0a6a1f1dSLionel Sambuc // dependency VFS alongside the output.
3886*0a6a1f1dSLionel Sambuc if (HaveModules && C.isForDiagnostics()) {
3887*0a6a1f1dSLionel Sambuc SmallString<128> VFSDir(Output.getFilename());
3888*0a6a1f1dSLionel Sambuc llvm::sys::path::replace_extension(VFSDir, ".cache");
3889*0a6a1f1dSLionel Sambuc // Add the cache directory as a temp so the crash diagnostics pick it up.
3890*0a6a1f1dSLionel Sambuc C.addTempFile(Args.MakeArgString(VFSDir));
3891*0a6a1f1dSLionel Sambuc
3892*0a6a1f1dSLionel Sambuc llvm::sys::path::append(VFSDir, "vfs");
3893*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-module-dependency-dir");
3894*0a6a1f1dSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(VFSDir));
3895f4a2713aSLionel Sambuc }
3896*0a6a1f1dSLionel Sambuc
3897*0a6a1f1dSLionel Sambuc if (HaveModules)
3898*0a6a1f1dSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_fmodules_user_build_path);
3899f4a2713aSLionel Sambuc
3900f4a2713aSLionel Sambuc // Pass through all -fmodules-ignore-macro arguments.
3901f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_fmodules_ignore_macro);
3902f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_fmodules_prune_interval);
3903f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_fmodules_prune_after);
3904f4a2713aSLionel Sambuc
3905*0a6a1f1dSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_fbuild_session_timestamp);
3906*0a6a1f1dSLionel Sambuc
3907*0a6a1f1dSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_fbuild_session_file)) {
3908*0a6a1f1dSLionel Sambuc if (Args.hasArg(options::OPT_fbuild_session_timestamp))
3909*0a6a1f1dSLionel Sambuc D.Diag(diag::err_drv_argument_not_allowed_with)
3910*0a6a1f1dSLionel Sambuc << A->getAsString(Args) << "-fbuild-session-timestamp";
3911*0a6a1f1dSLionel Sambuc
3912*0a6a1f1dSLionel Sambuc llvm::sys::fs::file_status Status;
3913*0a6a1f1dSLionel Sambuc if (llvm::sys::fs::status(A->getValue(), Status))
3914*0a6a1f1dSLionel Sambuc D.Diag(diag::err_drv_no_such_file) << A->getValue();
3915*0a6a1f1dSLionel Sambuc char TimeStamp[48];
3916*0a6a1f1dSLionel Sambuc snprintf(TimeStamp, sizeof(TimeStamp), "-fbuild-session-timestamp=%" PRIu64,
3917*0a6a1f1dSLionel Sambuc (uint64_t)Status.getLastModificationTime().toEpochTime());
3918*0a6a1f1dSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(TimeStamp));
3919*0a6a1f1dSLionel Sambuc }
3920*0a6a1f1dSLionel Sambuc
3921*0a6a1f1dSLionel Sambuc if (Args.getLastArg(options::OPT_fmodules_validate_once_per_build_session)) {
3922*0a6a1f1dSLionel Sambuc if (!Args.getLastArg(options::OPT_fbuild_session_timestamp,
3923*0a6a1f1dSLionel Sambuc options::OPT_fbuild_session_file))
3924*0a6a1f1dSLionel Sambuc D.Diag(diag::err_drv_modules_validate_once_requires_timestamp);
3925*0a6a1f1dSLionel Sambuc
3926*0a6a1f1dSLionel Sambuc Args.AddLastArg(CmdArgs,
3927*0a6a1f1dSLionel Sambuc options::OPT_fmodules_validate_once_per_build_session);
3928*0a6a1f1dSLionel Sambuc }
3929*0a6a1f1dSLionel Sambuc
3930*0a6a1f1dSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_fmodules_validate_system_headers);
3931*0a6a1f1dSLionel Sambuc
3932f4a2713aSLionel Sambuc // -faccess-control is default.
3933f4a2713aSLionel Sambuc if (Args.hasFlag(options::OPT_fno_access_control,
3934f4a2713aSLionel Sambuc options::OPT_faccess_control,
3935f4a2713aSLionel Sambuc false))
3936f4a2713aSLionel Sambuc CmdArgs.push_back("-fno-access-control");
3937f4a2713aSLionel Sambuc
3938f4a2713aSLionel Sambuc // -felide-constructors is the default.
3939f4a2713aSLionel Sambuc if (Args.hasFlag(options::OPT_fno_elide_constructors,
3940f4a2713aSLionel Sambuc options::OPT_felide_constructors,
3941f4a2713aSLionel Sambuc false))
3942f4a2713aSLionel Sambuc CmdArgs.push_back("-fno-elide-constructors");
3943f4a2713aSLionel Sambuc
3944f4a2713aSLionel Sambuc // -frtti is default.
3945f4a2713aSLionel Sambuc if (!Args.hasFlag(options::OPT_frtti, options::OPT_fno_rtti) ||
3946f4a2713aSLionel Sambuc KernelOrKext) {
3947f4a2713aSLionel Sambuc CmdArgs.push_back("-fno-rtti");
3948f4a2713aSLionel Sambuc
3949f4a2713aSLionel Sambuc // -fno-rtti cannot usefully be combined with -fsanitize=vptr.
3950f4a2713aSLionel Sambuc if (Sanitize.sanitizesVptr()) {
3951f4a2713aSLionel Sambuc std::string NoRttiArg =
3952f4a2713aSLionel Sambuc Args.getLastArg(options::OPT_mkernel,
3953f4a2713aSLionel Sambuc options::OPT_fapple_kext,
3954f4a2713aSLionel Sambuc options::OPT_fno_rtti)->getAsString(Args);
3955f4a2713aSLionel Sambuc D.Diag(diag::err_drv_argument_not_allowed_with)
3956f4a2713aSLionel Sambuc << "-fsanitize=vptr" << NoRttiArg;
3957f4a2713aSLionel Sambuc }
3958f4a2713aSLionel Sambuc }
3959f4a2713aSLionel Sambuc
3960f4a2713aSLionel Sambuc // -fshort-enums=0 is default for all architectures except Hexagon.
3961f4a2713aSLionel Sambuc if (Args.hasFlag(options::OPT_fshort_enums,
3962f4a2713aSLionel Sambuc options::OPT_fno_short_enums,
3963f4a2713aSLionel Sambuc getToolChain().getArch() ==
3964f4a2713aSLionel Sambuc llvm::Triple::hexagon))
3965f4a2713aSLionel Sambuc CmdArgs.push_back("-fshort-enums");
3966f4a2713aSLionel Sambuc
3967f4a2713aSLionel Sambuc // -fsigned-char is default.
3968f4a2713aSLionel Sambuc if (!Args.hasFlag(options::OPT_fsigned_char, options::OPT_funsigned_char,
3969f4a2713aSLionel Sambuc isSignedCharDefault(getToolChain().getTriple())))
3970f4a2713aSLionel Sambuc CmdArgs.push_back("-fno-signed-char");
3971f4a2713aSLionel Sambuc
3972f4a2713aSLionel Sambuc // -fthreadsafe-static is default.
3973f4a2713aSLionel Sambuc if (!Args.hasFlag(options::OPT_fthreadsafe_statics,
3974f4a2713aSLionel Sambuc options::OPT_fno_threadsafe_statics))
3975f4a2713aSLionel Sambuc CmdArgs.push_back("-fno-threadsafe-statics");
3976f4a2713aSLionel Sambuc
3977f4a2713aSLionel Sambuc // -fuse-cxa-atexit is default.
3978*0a6a1f1dSLionel Sambuc if (!Args.hasFlag(options::OPT_fuse_cxa_atexit,
3979*0a6a1f1dSLionel Sambuc options::OPT_fno_use_cxa_atexit,
3980*0a6a1f1dSLionel Sambuc !IsWindowsCygnus && !IsWindowsGNU &&
3981f4a2713aSLionel Sambuc getToolChain().getArch() != llvm::Triple::hexagon &&
3982f4a2713aSLionel Sambuc getToolChain().getArch() != llvm::Triple::xcore) ||
3983f4a2713aSLionel Sambuc KernelOrKext)
3984f4a2713aSLionel Sambuc CmdArgs.push_back("-fno-use-cxa-atexit");
3985f4a2713aSLionel Sambuc
3986f4a2713aSLionel Sambuc // -fms-extensions=0 is default.
3987f4a2713aSLionel Sambuc if (Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions,
3988*0a6a1f1dSLionel Sambuc IsWindowsMSVC))
3989f4a2713aSLionel Sambuc CmdArgs.push_back("-fms-extensions");
3990f4a2713aSLionel Sambuc
3991f4a2713aSLionel Sambuc // -fms-compatibility=0 is default.
3992f4a2713aSLionel Sambuc if (Args.hasFlag(options::OPT_fms_compatibility,
3993f4a2713aSLionel Sambuc options::OPT_fno_ms_compatibility,
3994*0a6a1f1dSLionel Sambuc (IsWindowsMSVC && Args.hasFlag(options::OPT_fms_extensions,
3995f4a2713aSLionel Sambuc options::OPT_fno_ms_extensions,
3996f4a2713aSLionel Sambuc true))))
3997f4a2713aSLionel Sambuc CmdArgs.push_back("-fms-compatibility");
3998f4a2713aSLionel Sambuc
3999*0a6a1f1dSLionel Sambuc // -fms-compatibility-version=17.00 is default.
4000f4a2713aSLionel Sambuc if (Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions,
4001*0a6a1f1dSLionel Sambuc IsWindowsMSVC) || Args.hasArg(options::OPT_fmsc_version) ||
4002*0a6a1f1dSLionel Sambuc Args.hasArg(options::OPT_fms_compatibility_version)) {
4003*0a6a1f1dSLionel Sambuc const Arg *MSCVersion = Args.getLastArg(options::OPT_fmsc_version);
4004*0a6a1f1dSLionel Sambuc const Arg *MSCompatibilityVersion =
4005*0a6a1f1dSLionel Sambuc Args.getLastArg(options::OPT_fms_compatibility_version);
4006f4a2713aSLionel Sambuc
4007*0a6a1f1dSLionel Sambuc if (MSCVersion && MSCompatibilityVersion)
4008*0a6a1f1dSLionel Sambuc D.Diag(diag::err_drv_argument_not_allowed_with)
4009*0a6a1f1dSLionel Sambuc << MSCVersion->getAsString(Args)
4010*0a6a1f1dSLionel Sambuc << MSCompatibilityVersion->getAsString(Args);
4011*0a6a1f1dSLionel Sambuc
4012*0a6a1f1dSLionel Sambuc std::string Ver;
4013*0a6a1f1dSLionel Sambuc if (MSCompatibilityVersion)
4014*0a6a1f1dSLionel Sambuc Ver = Args.getLastArgValue(options::OPT_fms_compatibility_version);
4015*0a6a1f1dSLionel Sambuc else if (MSCVersion)
4016*0a6a1f1dSLionel Sambuc Ver = getMSCompatibilityVersion(MSCVersion->getValue());
4017*0a6a1f1dSLionel Sambuc
4018*0a6a1f1dSLionel Sambuc if (Ver.empty())
4019*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-fms-compatibility-version=17.00");
4020*0a6a1f1dSLionel Sambuc else
4021*0a6a1f1dSLionel Sambuc CmdArgs.push_back(Args.MakeArgString("-fms-compatibility-version=" + Ver));
4022*0a6a1f1dSLionel Sambuc }
4023f4a2713aSLionel Sambuc
4024f4a2713aSLionel Sambuc // -fno-borland-extensions is default.
4025f4a2713aSLionel Sambuc if (Args.hasFlag(options::OPT_fborland_extensions,
4026f4a2713aSLionel Sambuc options::OPT_fno_borland_extensions, false))
4027f4a2713aSLionel Sambuc CmdArgs.push_back("-fborland-extensions");
4028f4a2713aSLionel Sambuc
4029f4a2713aSLionel Sambuc // -fno-delayed-template-parsing is default, except for Windows where MSVC STL
4030f4a2713aSLionel Sambuc // needs it.
4031f4a2713aSLionel Sambuc if (Args.hasFlag(options::OPT_fdelayed_template_parsing,
4032*0a6a1f1dSLionel Sambuc options::OPT_fno_delayed_template_parsing, IsWindowsMSVC))
4033f4a2713aSLionel Sambuc CmdArgs.push_back("-fdelayed-template-parsing");
4034f4a2713aSLionel Sambuc
4035f4a2713aSLionel Sambuc // -fgnu-keywords default varies depending on language; only pass if
4036f4a2713aSLionel Sambuc // specified.
4037f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_fgnu_keywords,
4038f4a2713aSLionel Sambuc options::OPT_fno_gnu_keywords))
4039f4a2713aSLionel Sambuc A->render(Args, CmdArgs);
4040f4a2713aSLionel Sambuc
4041f4a2713aSLionel Sambuc if (Args.hasFlag(options::OPT_fgnu89_inline,
4042f4a2713aSLionel Sambuc options::OPT_fno_gnu89_inline,
4043f4a2713aSLionel Sambuc false))
4044f4a2713aSLionel Sambuc CmdArgs.push_back("-fgnu89-inline");
4045f4a2713aSLionel Sambuc
4046f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_fno_inline))
4047f4a2713aSLionel Sambuc CmdArgs.push_back("-fno-inline");
4048f4a2713aSLionel Sambuc
4049f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_fno_inline_functions))
4050f4a2713aSLionel Sambuc CmdArgs.push_back("-fno-inline-functions");
4051f4a2713aSLionel Sambuc
4052f4a2713aSLionel Sambuc ObjCRuntime objcRuntime = AddObjCRuntimeArgs(Args, CmdArgs, rewriteKind);
4053f4a2713aSLionel Sambuc
4054f4a2713aSLionel Sambuc // -fobjc-dispatch-method is only relevant with the nonfragile-abi, and
4055*0a6a1f1dSLionel Sambuc // legacy is the default. Except for deployment taget of 10.5,
4056*0a6a1f1dSLionel Sambuc // next runtime is always legacy dispatch and -fno-objc-legacy-dispatch
4057*0a6a1f1dSLionel Sambuc // gets ignored silently.
4058*0a6a1f1dSLionel Sambuc if (objcRuntime.isNonFragile()) {
4059f4a2713aSLionel Sambuc if (!Args.hasFlag(options::OPT_fobjc_legacy_dispatch,
4060f4a2713aSLionel Sambuc options::OPT_fno_objc_legacy_dispatch,
4061f4a2713aSLionel Sambuc objcRuntime.isLegacyDispatchDefaultForArch(
4062f4a2713aSLionel Sambuc getToolChain().getArch()))) {
4063f4a2713aSLionel Sambuc if (getToolChain().UseObjCMixedDispatch())
4064f4a2713aSLionel Sambuc CmdArgs.push_back("-fobjc-dispatch-method=mixed");
4065f4a2713aSLionel Sambuc else
4066f4a2713aSLionel Sambuc CmdArgs.push_back("-fobjc-dispatch-method=non-legacy");
4067f4a2713aSLionel Sambuc }
4068f4a2713aSLionel Sambuc }
4069f4a2713aSLionel Sambuc
4070f4a2713aSLionel Sambuc // When ObjectiveC legacy runtime is in effect on MacOSX,
4071f4a2713aSLionel Sambuc // turn on the option to do Array/Dictionary subscripting
4072f4a2713aSLionel Sambuc // by default.
4073f4a2713aSLionel Sambuc if (getToolChain().getTriple().getArch() == llvm::Triple::x86 &&
4074f4a2713aSLionel Sambuc getToolChain().getTriple().isMacOSX() &&
4075f4a2713aSLionel Sambuc !getToolChain().getTriple().isMacOSXVersionLT(10, 7) &&
4076f4a2713aSLionel Sambuc objcRuntime.getKind() == ObjCRuntime::FragileMacOSX &&
4077f4a2713aSLionel Sambuc objcRuntime.isNeXTFamily())
4078f4a2713aSLionel Sambuc CmdArgs.push_back("-fobjc-subscripting-legacy-runtime");
4079f4a2713aSLionel Sambuc
4080f4a2713aSLionel Sambuc // -fencode-extended-block-signature=1 is default.
4081f4a2713aSLionel Sambuc if (getToolChain().IsEncodeExtendedBlockSignatureDefault()) {
4082f4a2713aSLionel Sambuc CmdArgs.push_back("-fencode-extended-block-signature");
4083f4a2713aSLionel Sambuc }
4084f4a2713aSLionel Sambuc
4085f4a2713aSLionel Sambuc // Allow -fno-objc-arr to trump -fobjc-arr/-fobjc-arc.
4086f4a2713aSLionel Sambuc // NOTE: This logic is duplicated in ToolChains.cpp.
4087f4a2713aSLionel Sambuc bool ARC = isObjCAutoRefCount(Args);
4088f4a2713aSLionel Sambuc if (ARC) {
4089f4a2713aSLionel Sambuc getToolChain().CheckObjCARC();
4090f4a2713aSLionel Sambuc
4091f4a2713aSLionel Sambuc CmdArgs.push_back("-fobjc-arc");
4092f4a2713aSLionel Sambuc
4093f4a2713aSLionel Sambuc // FIXME: It seems like this entire block, and several around it should be
4094f4a2713aSLionel Sambuc // wrapped in isObjC, but for now we just use it here as this is where it
4095f4a2713aSLionel Sambuc // was being used previously.
4096f4a2713aSLionel Sambuc if (types::isCXX(InputType) && types::isObjC(InputType)) {
4097f4a2713aSLionel Sambuc if (getToolChain().GetCXXStdlibType(Args) == ToolChain::CST_Libcxx)
4098f4a2713aSLionel Sambuc CmdArgs.push_back("-fobjc-arc-cxxlib=libc++");
4099f4a2713aSLionel Sambuc else
4100f4a2713aSLionel Sambuc CmdArgs.push_back("-fobjc-arc-cxxlib=libstdc++");
4101f4a2713aSLionel Sambuc }
4102f4a2713aSLionel Sambuc
4103f4a2713aSLionel Sambuc // Allow the user to enable full exceptions code emission.
4104f4a2713aSLionel Sambuc // We define off for Objective-CC, on for Objective-C++.
4105f4a2713aSLionel Sambuc if (Args.hasFlag(options::OPT_fobjc_arc_exceptions,
4106f4a2713aSLionel Sambuc options::OPT_fno_objc_arc_exceptions,
4107f4a2713aSLionel Sambuc /*default*/ types::isCXX(InputType)))
4108f4a2713aSLionel Sambuc CmdArgs.push_back("-fobjc-arc-exceptions");
4109f4a2713aSLionel Sambuc }
4110f4a2713aSLionel Sambuc
4111f4a2713aSLionel Sambuc // -fobjc-infer-related-result-type is the default, except in the Objective-C
4112f4a2713aSLionel Sambuc // rewriter.
4113f4a2713aSLionel Sambuc if (rewriteKind != RK_None)
4114f4a2713aSLionel Sambuc CmdArgs.push_back("-fno-objc-infer-related-result-type");
4115f4a2713aSLionel Sambuc
4116f4a2713aSLionel Sambuc // Handle -fobjc-gc and -fobjc-gc-only. They are exclusive, and -fobjc-gc-only
4117f4a2713aSLionel Sambuc // takes precedence.
4118f4a2713aSLionel Sambuc const Arg *GCArg = Args.getLastArg(options::OPT_fobjc_gc_only);
4119f4a2713aSLionel Sambuc if (!GCArg)
4120f4a2713aSLionel Sambuc GCArg = Args.getLastArg(options::OPT_fobjc_gc);
4121f4a2713aSLionel Sambuc if (GCArg) {
4122f4a2713aSLionel Sambuc if (ARC) {
4123f4a2713aSLionel Sambuc D.Diag(diag::err_drv_objc_gc_arr)
4124f4a2713aSLionel Sambuc << GCArg->getAsString(Args);
4125f4a2713aSLionel Sambuc } else if (getToolChain().SupportsObjCGC()) {
4126f4a2713aSLionel Sambuc GCArg->render(Args, CmdArgs);
4127f4a2713aSLionel Sambuc } else {
4128f4a2713aSLionel Sambuc // FIXME: We should move this to a hard error.
4129f4a2713aSLionel Sambuc D.Diag(diag::warn_drv_objc_gc_unsupported)
4130f4a2713aSLionel Sambuc << GCArg->getAsString(Args);
4131f4a2713aSLionel Sambuc }
4132f4a2713aSLionel Sambuc }
4133f4a2713aSLionel Sambuc
4134*0a6a1f1dSLionel Sambuc // Handle GCC-style exception args.
4135*0a6a1f1dSLionel Sambuc if (!C.getDriver().IsCLMode())
4136*0a6a1f1dSLionel Sambuc addExceptionArgs(Args, InputType, getToolChain().getTriple(), KernelOrKext,
4137*0a6a1f1dSLionel Sambuc objcRuntime, CmdArgs);
4138f4a2713aSLionel Sambuc
4139f4a2713aSLionel Sambuc if (getToolChain().UseSjLjExceptions())
4140f4a2713aSLionel Sambuc CmdArgs.push_back("-fsjlj-exceptions");
4141f4a2713aSLionel Sambuc
4142f4a2713aSLionel Sambuc // C++ "sane" operator new.
4143f4a2713aSLionel Sambuc if (!Args.hasFlag(options::OPT_fassume_sane_operator_new,
4144f4a2713aSLionel Sambuc options::OPT_fno_assume_sane_operator_new))
4145f4a2713aSLionel Sambuc CmdArgs.push_back("-fno-assume-sane-operator-new");
4146f4a2713aSLionel Sambuc
4147f4a2713aSLionel Sambuc // -fconstant-cfstrings is default, and may be subject to argument translation
4148f4a2713aSLionel Sambuc // on Darwin.
4149f4a2713aSLionel Sambuc if (!Args.hasFlag(options::OPT_fconstant_cfstrings,
4150f4a2713aSLionel Sambuc options::OPT_fno_constant_cfstrings) ||
4151f4a2713aSLionel Sambuc !Args.hasFlag(options::OPT_mconstant_cfstrings,
4152f4a2713aSLionel Sambuc options::OPT_mno_constant_cfstrings))
4153f4a2713aSLionel Sambuc CmdArgs.push_back("-fno-constant-cfstrings");
4154f4a2713aSLionel Sambuc
4155f4a2713aSLionel Sambuc // -fshort-wchar default varies depending on platform; only
4156f4a2713aSLionel Sambuc // pass if specified.
4157*0a6a1f1dSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_fshort_wchar,
4158*0a6a1f1dSLionel Sambuc options::OPT_fno_short_wchar))
4159f4a2713aSLionel Sambuc A->render(Args, CmdArgs);
4160f4a2713aSLionel Sambuc
4161f4a2713aSLionel Sambuc // -fno-pascal-strings is default, only pass non-default.
4162f4a2713aSLionel Sambuc if (Args.hasFlag(options::OPT_fpascal_strings,
4163f4a2713aSLionel Sambuc options::OPT_fno_pascal_strings,
4164f4a2713aSLionel Sambuc false))
4165f4a2713aSLionel Sambuc CmdArgs.push_back("-fpascal-strings");
4166f4a2713aSLionel Sambuc
4167f4a2713aSLionel Sambuc // Honor -fpack-struct= and -fpack-struct, if given. Note that
4168f4a2713aSLionel Sambuc // -fno-pack-struct doesn't apply to -fpack-struct=.
4169f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_fpack_struct_EQ)) {
4170f4a2713aSLionel Sambuc std::string PackStructStr = "-fpack-struct=";
4171f4a2713aSLionel Sambuc PackStructStr += A->getValue();
4172f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(PackStructStr));
4173f4a2713aSLionel Sambuc } else if (Args.hasFlag(options::OPT_fpack_struct,
4174f4a2713aSLionel Sambuc options::OPT_fno_pack_struct, false)) {
4175f4a2713aSLionel Sambuc CmdArgs.push_back("-fpack-struct=1");
4176f4a2713aSLionel Sambuc }
4177f4a2713aSLionel Sambuc
4178*0a6a1f1dSLionel Sambuc // Handle -fmax-type-align=N and -fno-type-align
4179*0a6a1f1dSLionel Sambuc bool SkipMaxTypeAlign = Args.hasArg(options::OPT_fno_max_type_align);
4180*0a6a1f1dSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_fmax_type_align_EQ)) {
4181*0a6a1f1dSLionel Sambuc if (!SkipMaxTypeAlign) {
4182*0a6a1f1dSLionel Sambuc std::string MaxTypeAlignStr = "-fmax-type-align=";
4183*0a6a1f1dSLionel Sambuc MaxTypeAlignStr += A->getValue();
4184*0a6a1f1dSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(MaxTypeAlignStr));
4185*0a6a1f1dSLionel Sambuc }
4186*0a6a1f1dSLionel Sambuc } else if (getToolChain().getTriple().isOSDarwin()) {
4187*0a6a1f1dSLionel Sambuc if (!SkipMaxTypeAlign) {
4188*0a6a1f1dSLionel Sambuc std::string MaxTypeAlignStr = "-fmax-type-align=16";
4189*0a6a1f1dSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(MaxTypeAlignStr));
4190*0a6a1f1dSLionel Sambuc }
4191*0a6a1f1dSLionel Sambuc }
4192*0a6a1f1dSLionel Sambuc
4193f4a2713aSLionel Sambuc if (KernelOrKext || isNoCommonDefault(getToolChain().getTriple())) {
4194f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_fcommon))
4195f4a2713aSLionel Sambuc CmdArgs.push_back("-fno-common");
4196f4a2713aSLionel Sambuc Args.ClaimAllArgs(options::OPT_fno_common);
4197f4a2713aSLionel Sambuc }
4198f4a2713aSLionel Sambuc
4199f4a2713aSLionel Sambuc // -fcommon is default, only pass non-default.
4200f4a2713aSLionel Sambuc else if (!Args.hasFlag(options::OPT_fcommon, options::OPT_fno_common))
4201f4a2713aSLionel Sambuc CmdArgs.push_back("-fno-common");
4202f4a2713aSLionel Sambuc
4203f4a2713aSLionel Sambuc // -fsigned-bitfields is default, and clang doesn't yet support
4204f4a2713aSLionel Sambuc // -funsigned-bitfields.
4205f4a2713aSLionel Sambuc if (!Args.hasFlag(options::OPT_fsigned_bitfields,
4206f4a2713aSLionel Sambuc options::OPT_funsigned_bitfields))
4207f4a2713aSLionel Sambuc D.Diag(diag::warn_drv_clang_unsupported)
4208f4a2713aSLionel Sambuc << Args.getLastArg(options::OPT_funsigned_bitfields)->getAsString(Args);
4209f4a2713aSLionel Sambuc
4210f4a2713aSLionel Sambuc // -fsigned-bitfields is default, and clang doesn't support -fno-for-scope.
4211f4a2713aSLionel Sambuc if (!Args.hasFlag(options::OPT_ffor_scope,
4212f4a2713aSLionel Sambuc options::OPT_fno_for_scope))
4213f4a2713aSLionel Sambuc D.Diag(diag::err_drv_clang_unsupported)
4214f4a2713aSLionel Sambuc << Args.getLastArg(options::OPT_fno_for_scope)->getAsString(Args);
4215f4a2713aSLionel Sambuc
4216*0a6a1f1dSLionel Sambuc // -finput_charset=UTF-8 is default. Reject others
4217*0a6a1f1dSLionel Sambuc if (Arg *inputCharset = Args.getLastArg(
4218*0a6a1f1dSLionel Sambuc options::OPT_finput_charset_EQ)) {
4219*0a6a1f1dSLionel Sambuc StringRef value = inputCharset->getValue();
4220*0a6a1f1dSLionel Sambuc if (value != "UTF-8")
4221*0a6a1f1dSLionel Sambuc D.Diag(diag::err_drv_invalid_value) << inputCharset->getAsString(Args) << value;
4222*0a6a1f1dSLionel Sambuc }
4223*0a6a1f1dSLionel Sambuc
4224*0a6a1f1dSLionel Sambuc // -fexec_charset=UTF-8 is default. Reject others
4225*0a6a1f1dSLionel Sambuc if (Arg *execCharset = Args.getLastArg(
4226*0a6a1f1dSLionel Sambuc options::OPT_fexec_charset_EQ)) {
4227*0a6a1f1dSLionel Sambuc StringRef value = execCharset->getValue();
4228*0a6a1f1dSLionel Sambuc if (value != "UTF-8")
4229*0a6a1f1dSLionel Sambuc D.Diag(diag::err_drv_invalid_value) << execCharset->getAsString(Args) << value;
4230*0a6a1f1dSLionel Sambuc }
4231*0a6a1f1dSLionel Sambuc
4232f4a2713aSLionel Sambuc // -fcaret-diagnostics is default.
4233f4a2713aSLionel Sambuc if (!Args.hasFlag(options::OPT_fcaret_diagnostics,
4234f4a2713aSLionel Sambuc options::OPT_fno_caret_diagnostics, true))
4235f4a2713aSLionel Sambuc CmdArgs.push_back("-fno-caret-diagnostics");
4236f4a2713aSLionel Sambuc
4237f4a2713aSLionel Sambuc // -fdiagnostics-fixit-info is default, only pass non-default.
4238f4a2713aSLionel Sambuc if (!Args.hasFlag(options::OPT_fdiagnostics_fixit_info,
4239f4a2713aSLionel Sambuc options::OPT_fno_diagnostics_fixit_info))
4240f4a2713aSLionel Sambuc CmdArgs.push_back("-fno-diagnostics-fixit-info");
4241f4a2713aSLionel Sambuc
4242f4a2713aSLionel Sambuc // Enable -fdiagnostics-show-option by default.
4243f4a2713aSLionel Sambuc if (Args.hasFlag(options::OPT_fdiagnostics_show_option,
4244f4a2713aSLionel Sambuc options::OPT_fno_diagnostics_show_option))
4245f4a2713aSLionel Sambuc CmdArgs.push_back("-fdiagnostics-show-option");
4246f4a2713aSLionel Sambuc
4247f4a2713aSLionel Sambuc if (const Arg *A =
4248f4a2713aSLionel Sambuc Args.getLastArg(options::OPT_fdiagnostics_show_category_EQ)) {
4249f4a2713aSLionel Sambuc CmdArgs.push_back("-fdiagnostics-show-category");
4250f4a2713aSLionel Sambuc CmdArgs.push_back(A->getValue());
4251f4a2713aSLionel Sambuc }
4252f4a2713aSLionel Sambuc
4253f4a2713aSLionel Sambuc if (const Arg *A =
4254f4a2713aSLionel Sambuc Args.getLastArg(options::OPT_fdiagnostics_format_EQ)) {
4255f4a2713aSLionel Sambuc CmdArgs.push_back("-fdiagnostics-format");
4256f4a2713aSLionel Sambuc CmdArgs.push_back(A->getValue());
4257f4a2713aSLionel Sambuc }
4258f4a2713aSLionel Sambuc
4259f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(
4260f4a2713aSLionel Sambuc options::OPT_fdiagnostics_show_note_include_stack,
4261f4a2713aSLionel Sambuc options::OPT_fno_diagnostics_show_note_include_stack)) {
4262f4a2713aSLionel Sambuc if (A->getOption().matches(
4263f4a2713aSLionel Sambuc options::OPT_fdiagnostics_show_note_include_stack))
4264f4a2713aSLionel Sambuc CmdArgs.push_back("-fdiagnostics-show-note-include-stack");
4265f4a2713aSLionel Sambuc else
4266f4a2713aSLionel Sambuc CmdArgs.push_back("-fno-diagnostics-show-note-include-stack");
4267f4a2713aSLionel Sambuc }
4268f4a2713aSLionel Sambuc
4269f4a2713aSLionel Sambuc // Color diagnostics are the default, unless the terminal doesn't support
4270f4a2713aSLionel Sambuc // them.
4271f4a2713aSLionel Sambuc // Support both clang's -f[no-]color-diagnostics and gcc's
4272f4a2713aSLionel Sambuc // -f[no-]diagnostics-colors[=never|always|auto].
4273f4a2713aSLionel Sambuc enum { Colors_On, Colors_Off, Colors_Auto } ShowColors = Colors_Auto;
4274*0a6a1f1dSLionel Sambuc for (const auto &Arg : Args) {
4275*0a6a1f1dSLionel Sambuc const Option &O = Arg->getOption();
4276f4a2713aSLionel Sambuc if (!O.matches(options::OPT_fcolor_diagnostics) &&
4277f4a2713aSLionel Sambuc !O.matches(options::OPT_fdiagnostics_color) &&
4278f4a2713aSLionel Sambuc !O.matches(options::OPT_fno_color_diagnostics) &&
4279f4a2713aSLionel Sambuc !O.matches(options::OPT_fno_diagnostics_color) &&
4280f4a2713aSLionel Sambuc !O.matches(options::OPT_fdiagnostics_color_EQ))
4281f4a2713aSLionel Sambuc continue;
4282f4a2713aSLionel Sambuc
4283*0a6a1f1dSLionel Sambuc Arg->claim();
4284f4a2713aSLionel Sambuc if (O.matches(options::OPT_fcolor_diagnostics) ||
4285f4a2713aSLionel Sambuc O.matches(options::OPT_fdiagnostics_color)) {
4286f4a2713aSLionel Sambuc ShowColors = Colors_On;
4287f4a2713aSLionel Sambuc } else if (O.matches(options::OPT_fno_color_diagnostics) ||
4288f4a2713aSLionel Sambuc O.matches(options::OPT_fno_diagnostics_color)) {
4289f4a2713aSLionel Sambuc ShowColors = Colors_Off;
4290f4a2713aSLionel Sambuc } else {
4291f4a2713aSLionel Sambuc assert(O.matches(options::OPT_fdiagnostics_color_EQ));
4292*0a6a1f1dSLionel Sambuc StringRef value(Arg->getValue());
4293f4a2713aSLionel Sambuc if (value == "always")
4294f4a2713aSLionel Sambuc ShowColors = Colors_On;
4295f4a2713aSLionel Sambuc else if (value == "never")
4296f4a2713aSLionel Sambuc ShowColors = Colors_Off;
4297f4a2713aSLionel Sambuc else if (value == "auto")
4298f4a2713aSLionel Sambuc ShowColors = Colors_Auto;
4299f4a2713aSLionel Sambuc else
4300f4a2713aSLionel Sambuc getToolChain().getDriver().Diag(diag::err_drv_clang_unsupported)
4301f4a2713aSLionel Sambuc << ("-fdiagnostics-color=" + value).str();
4302f4a2713aSLionel Sambuc }
4303f4a2713aSLionel Sambuc }
4304f4a2713aSLionel Sambuc if (ShowColors == Colors_On ||
4305f4a2713aSLionel Sambuc (ShowColors == Colors_Auto && llvm::sys::Process::StandardErrHasColors()))
4306f4a2713aSLionel Sambuc CmdArgs.push_back("-fcolor-diagnostics");
4307f4a2713aSLionel Sambuc
4308f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_fansi_escape_codes))
4309f4a2713aSLionel Sambuc CmdArgs.push_back("-fansi-escape-codes");
4310f4a2713aSLionel Sambuc
4311f4a2713aSLionel Sambuc if (!Args.hasFlag(options::OPT_fshow_source_location,
4312f4a2713aSLionel Sambuc options::OPT_fno_show_source_location))
4313f4a2713aSLionel Sambuc CmdArgs.push_back("-fno-show-source-location");
4314f4a2713aSLionel Sambuc
4315f4a2713aSLionel Sambuc if (!Args.hasFlag(options::OPT_fshow_column,
4316f4a2713aSLionel Sambuc options::OPT_fno_show_column,
4317f4a2713aSLionel Sambuc true))
4318f4a2713aSLionel Sambuc CmdArgs.push_back("-fno-show-column");
4319f4a2713aSLionel Sambuc
4320f4a2713aSLionel Sambuc if (!Args.hasFlag(options::OPT_fspell_checking,
4321f4a2713aSLionel Sambuc options::OPT_fno_spell_checking))
4322f4a2713aSLionel Sambuc CmdArgs.push_back("-fno-spell-checking");
4323f4a2713aSLionel Sambuc
4324f4a2713aSLionel Sambuc
4325f4a2713aSLionel Sambuc // -fno-asm-blocks is default.
4326f4a2713aSLionel Sambuc if (Args.hasFlag(options::OPT_fasm_blocks, options::OPT_fno_asm_blocks,
4327f4a2713aSLionel Sambuc false))
4328f4a2713aSLionel Sambuc CmdArgs.push_back("-fasm-blocks");
4329f4a2713aSLionel Sambuc
4330f4a2713aSLionel Sambuc // Enable vectorization per default according to the optimization level
4331f4a2713aSLionel Sambuc // selected. For optimization levels that want vectorization we use the alias
4332f4a2713aSLionel Sambuc // option to simplify the hasFlag logic.
4333*0a6a1f1dSLionel Sambuc bool EnableVec = shouldEnableVectorizerAtOLevel(Args, false);
4334f4a2713aSLionel Sambuc OptSpecifier VectorizeAliasOption = EnableVec ? options::OPT_O_Group :
4335f4a2713aSLionel Sambuc options::OPT_fvectorize;
4336f4a2713aSLionel Sambuc if (Args.hasFlag(options::OPT_fvectorize, VectorizeAliasOption,
4337f4a2713aSLionel Sambuc options::OPT_fno_vectorize, EnableVec))
4338f4a2713aSLionel Sambuc CmdArgs.push_back("-vectorize-loops");
4339f4a2713aSLionel Sambuc
4340*0a6a1f1dSLionel Sambuc // -fslp-vectorize is enabled based on the optimization level selected.
4341*0a6a1f1dSLionel Sambuc bool EnableSLPVec = shouldEnableVectorizerAtOLevel(Args, true);
4342*0a6a1f1dSLionel Sambuc OptSpecifier SLPVectAliasOption = EnableSLPVec ? options::OPT_O_Group :
4343*0a6a1f1dSLionel Sambuc options::OPT_fslp_vectorize;
4344*0a6a1f1dSLionel Sambuc if (Args.hasFlag(options::OPT_fslp_vectorize, SLPVectAliasOption,
4345*0a6a1f1dSLionel Sambuc options::OPT_fno_slp_vectorize, EnableSLPVec))
4346f4a2713aSLionel Sambuc CmdArgs.push_back("-vectorize-slp");
4347f4a2713aSLionel Sambuc
4348f4a2713aSLionel Sambuc // -fno-slp-vectorize-aggressive is default.
4349f4a2713aSLionel Sambuc if (Args.hasFlag(options::OPT_fslp_vectorize_aggressive,
4350f4a2713aSLionel Sambuc options::OPT_fno_slp_vectorize_aggressive, false))
4351f4a2713aSLionel Sambuc CmdArgs.push_back("-vectorize-slp-aggressive");
4352f4a2713aSLionel Sambuc
4353f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_fshow_overloads_EQ))
4354f4a2713aSLionel Sambuc A->render(Args, CmdArgs);
4355f4a2713aSLionel Sambuc
4356f4a2713aSLionel Sambuc // -fdollars-in-identifiers default varies depending on platform and
4357f4a2713aSLionel Sambuc // language; only pass if specified.
4358f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_fdollars_in_identifiers,
4359f4a2713aSLionel Sambuc options::OPT_fno_dollars_in_identifiers)) {
4360f4a2713aSLionel Sambuc if (A->getOption().matches(options::OPT_fdollars_in_identifiers))
4361f4a2713aSLionel Sambuc CmdArgs.push_back("-fdollars-in-identifiers");
4362f4a2713aSLionel Sambuc else
4363f4a2713aSLionel Sambuc CmdArgs.push_back("-fno-dollars-in-identifiers");
4364f4a2713aSLionel Sambuc }
4365f4a2713aSLionel Sambuc
4366f4a2713aSLionel Sambuc // -funit-at-a-time is default, and we don't support -fno-unit-at-a-time for
4367f4a2713aSLionel Sambuc // practical purposes.
4368f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_funit_at_a_time,
4369f4a2713aSLionel Sambuc options::OPT_fno_unit_at_a_time)) {
4370f4a2713aSLionel Sambuc if (A->getOption().matches(options::OPT_fno_unit_at_a_time))
4371f4a2713aSLionel Sambuc D.Diag(diag::warn_drv_clang_unsupported) << A->getAsString(Args);
4372f4a2713aSLionel Sambuc }
4373f4a2713aSLionel Sambuc
4374f4a2713aSLionel Sambuc if (Args.hasFlag(options::OPT_fapple_pragma_pack,
4375f4a2713aSLionel Sambuc options::OPT_fno_apple_pragma_pack, false))
4376f4a2713aSLionel Sambuc CmdArgs.push_back("-fapple-pragma-pack");
4377f4a2713aSLionel Sambuc
4378f4a2713aSLionel Sambuc // le32-specific flags:
4379f4a2713aSLionel Sambuc // -fno-math-builtin: clang should not convert math builtins to intrinsics
4380f4a2713aSLionel Sambuc // by default.
4381f4a2713aSLionel Sambuc if (getToolChain().getArch() == llvm::Triple::le32) {
4382f4a2713aSLionel Sambuc CmdArgs.push_back("-fno-math-builtin");
4383f4a2713aSLionel Sambuc }
4384f4a2713aSLionel Sambuc
4385f4a2713aSLionel Sambuc // Default to -fno-builtin-str{cat,cpy} on Darwin for ARM.
4386f4a2713aSLionel Sambuc //
4387f4a2713aSLionel Sambuc // FIXME: This is disabled until clang -cc1 supports -fno-builtin-foo. PR4941.
4388f4a2713aSLionel Sambuc #if 0
4389f4a2713aSLionel Sambuc if (getToolChain().getTriple().isOSDarwin() &&
4390f4a2713aSLionel Sambuc (getToolChain().getArch() == llvm::Triple::arm ||
4391f4a2713aSLionel Sambuc getToolChain().getArch() == llvm::Triple::thumb)) {
4392f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_fbuiltin_strcat))
4393f4a2713aSLionel Sambuc CmdArgs.push_back("-fno-builtin-strcat");
4394f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_fbuiltin_strcpy))
4395f4a2713aSLionel Sambuc CmdArgs.push_back("-fno-builtin-strcpy");
4396f4a2713aSLionel Sambuc }
4397f4a2713aSLionel Sambuc #endif
4398f4a2713aSLionel Sambuc
4399*0a6a1f1dSLionel Sambuc // Enable rewrite includes if the user's asked for it or if we're generating
4400*0a6a1f1dSLionel Sambuc // diagnostics.
4401*0a6a1f1dSLionel Sambuc // TODO: Once -module-dependency-dir works with -frewrite-includes it'd be
4402*0a6a1f1dSLionel Sambuc // nice to enable this when doing a crashdump for modules as well.
4403*0a6a1f1dSLionel Sambuc if (Args.hasFlag(options::OPT_frewrite_includes,
4404*0a6a1f1dSLionel Sambuc options::OPT_fno_rewrite_includes, false) ||
4405*0a6a1f1dSLionel Sambuc (C.isForDiagnostics() && !HaveModules))
4406*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-frewrite-includes");
4407*0a6a1f1dSLionel Sambuc
4408f4a2713aSLionel Sambuc // Only allow -traditional or -traditional-cpp outside in preprocessing modes.
4409f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_traditional,
4410f4a2713aSLionel Sambuc options::OPT_traditional_cpp)) {
4411f4a2713aSLionel Sambuc if (isa<PreprocessJobAction>(JA))
4412f4a2713aSLionel Sambuc CmdArgs.push_back("-traditional-cpp");
4413f4a2713aSLionel Sambuc else
4414f4a2713aSLionel Sambuc D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
4415f4a2713aSLionel Sambuc }
4416f4a2713aSLionel Sambuc
4417f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_dM);
4418f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_dD);
4419f4a2713aSLionel Sambuc
4420f4a2713aSLionel Sambuc // Handle serialized diagnostics.
4421f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT__serialize_diags)) {
4422f4a2713aSLionel Sambuc CmdArgs.push_back("-serialize-diagnostic-file");
4423f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(A->getValue()));
4424f4a2713aSLionel Sambuc }
4425f4a2713aSLionel Sambuc
4426f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_fretain_comments_from_system_headers))
4427f4a2713aSLionel Sambuc CmdArgs.push_back("-fretain-comments-from-system-headers");
4428f4a2713aSLionel Sambuc
4429f4a2713aSLionel Sambuc // Forward -fcomment-block-commands to -cc1.
4430f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_fcomment_block_commands);
4431f4a2713aSLionel Sambuc // Forward -fparse-all-comments to -cc1.
4432f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_fparse_all_comments);
4433f4a2713aSLionel Sambuc
4434f4a2713aSLionel Sambuc // Forward -Xclang arguments to -cc1, and -mllvm arguments to the LLVM option
4435f4a2713aSLionel Sambuc // parser.
4436f4a2713aSLionel Sambuc Args.AddAllArgValues(CmdArgs, options::OPT_Xclang);
4437*0a6a1f1dSLionel Sambuc bool OptDisabled = false;
4438f4a2713aSLionel Sambuc for (arg_iterator it = Args.filtered_begin(options::OPT_mllvm),
4439f4a2713aSLionel Sambuc ie = Args.filtered_end(); it != ie; ++it) {
4440f4a2713aSLionel Sambuc (*it)->claim();
4441f4a2713aSLionel Sambuc
4442f4a2713aSLionel Sambuc // We translate this by hand to the -cc1 argument, since nightly test uses
4443f4a2713aSLionel Sambuc // it and developers have been trained to spell it with -mllvm.
4444*0a6a1f1dSLionel Sambuc if (StringRef((*it)->getValue(0)) == "-disable-llvm-optzns") {
4445f4a2713aSLionel Sambuc CmdArgs.push_back("-disable-llvm-optzns");
4446*0a6a1f1dSLionel Sambuc OptDisabled = true;
4447*0a6a1f1dSLionel Sambuc } else
4448f4a2713aSLionel Sambuc (*it)->render(Args, CmdArgs);
4449f4a2713aSLionel Sambuc }
4450f4a2713aSLionel Sambuc
4451*0a6a1f1dSLionel Sambuc // With -save-temps, we want to save the unoptimized bitcode output from the
4452*0a6a1f1dSLionel Sambuc // CompileJobAction, so disable optimizations if they are not already
4453*0a6a1f1dSLionel Sambuc // disabled.
4454*0a6a1f1dSLionel Sambuc if (Args.hasArg(options::OPT_save_temps) && !OptDisabled &&
4455*0a6a1f1dSLionel Sambuc isa<CompileJobAction>(JA))
4456*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-disable-llvm-optzns");
4457*0a6a1f1dSLionel Sambuc
4458f4a2713aSLionel Sambuc if (Output.getType() == types::TY_Dependencies) {
4459f4a2713aSLionel Sambuc // Handled with other dependency code.
4460f4a2713aSLionel Sambuc } else if (Output.isFilename()) {
4461f4a2713aSLionel Sambuc CmdArgs.push_back("-o");
4462f4a2713aSLionel Sambuc CmdArgs.push_back(Output.getFilename());
4463f4a2713aSLionel Sambuc } else {
4464f4a2713aSLionel Sambuc assert(Output.isNothing() && "Invalid output.");
4465f4a2713aSLionel Sambuc }
4466f4a2713aSLionel Sambuc
4467*0a6a1f1dSLionel Sambuc for (const auto &II : Inputs) {
4468*0a6a1f1dSLionel Sambuc addDashXForInput(Args, II, CmdArgs);
4469*0a6a1f1dSLionel Sambuc
4470f4a2713aSLionel Sambuc if (II.isFilename())
4471f4a2713aSLionel Sambuc CmdArgs.push_back(II.getFilename());
4472f4a2713aSLionel Sambuc else
4473f4a2713aSLionel Sambuc II.getInputArg().renderAsInput(Args, CmdArgs);
4474f4a2713aSLionel Sambuc }
4475f4a2713aSLionel Sambuc
4476f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_undef);
4477f4a2713aSLionel Sambuc
4478f4a2713aSLionel Sambuc const char *Exec = getToolChain().getDriver().getClangProgramPath();
4479f4a2713aSLionel Sambuc
4480f4a2713aSLionel Sambuc // Optionally embed the -cc1 level arguments into the debug info, for build
4481f4a2713aSLionel Sambuc // analysis.
4482f4a2713aSLionel Sambuc if (getToolChain().UseDwarfDebugFlags()) {
4483f4a2713aSLionel Sambuc ArgStringList OriginalArgs;
4484*0a6a1f1dSLionel Sambuc for (const auto &Arg : Args)
4485*0a6a1f1dSLionel Sambuc Arg->render(Args, OriginalArgs);
4486f4a2713aSLionel Sambuc
4487f4a2713aSLionel Sambuc SmallString<256> Flags;
4488f4a2713aSLionel Sambuc Flags += Exec;
4489f4a2713aSLionel Sambuc for (unsigned i = 0, e = OriginalArgs.size(); i != e; ++i) {
4490*0a6a1f1dSLionel Sambuc SmallString<128> EscapedArg;
4491*0a6a1f1dSLionel Sambuc EscapeSpacesAndBackslashes(OriginalArgs[i], EscapedArg);
4492f4a2713aSLionel Sambuc Flags += " ";
4493*0a6a1f1dSLionel Sambuc Flags += EscapedArg;
4494f4a2713aSLionel Sambuc }
4495f4a2713aSLionel Sambuc CmdArgs.push_back("-dwarf-debug-flags");
4496f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(Flags.str()));
4497f4a2713aSLionel Sambuc }
4498f4a2713aSLionel Sambuc
4499f4a2713aSLionel Sambuc // Add the split debug info name to the command lines here so we
4500f4a2713aSLionel Sambuc // can propagate it to the backend.
4501f4a2713aSLionel Sambuc bool SplitDwarf = Args.hasArg(options::OPT_gsplit_dwarf) &&
4502f4a2713aSLionel Sambuc getToolChain().getTriple().isOSLinux() &&
4503*0a6a1f1dSLionel Sambuc (isa<AssembleJobAction>(JA) || isa<CompileJobAction>(JA) ||
4504*0a6a1f1dSLionel Sambuc isa<BackendJobAction>(JA));
4505f4a2713aSLionel Sambuc const char *SplitDwarfOut;
4506f4a2713aSLionel Sambuc if (SplitDwarf) {
4507f4a2713aSLionel Sambuc CmdArgs.push_back("-split-dwarf-file");
4508f4a2713aSLionel Sambuc SplitDwarfOut = SplitDebugName(Args, Inputs);
4509f4a2713aSLionel Sambuc CmdArgs.push_back(SplitDwarfOut);
4510f4a2713aSLionel Sambuc }
4511f4a2713aSLionel Sambuc
4512f4a2713aSLionel Sambuc // Finally add the compile command to the compilation.
4513*0a6a1f1dSLionel Sambuc if (Args.hasArg(options::OPT__SLASH_fallback) &&
4514*0a6a1f1dSLionel Sambuc Output.getType() == types::TY_Object &&
4515*0a6a1f1dSLionel Sambuc (InputType == types::TY_C || InputType == types::TY_CXX)) {
4516*0a6a1f1dSLionel Sambuc auto CLCommand =
4517*0a6a1f1dSLionel Sambuc getCLFallback()->GetCommand(C, JA, Output, Inputs, Args, LinkingOutput);
4518*0a6a1f1dSLionel Sambuc C.addCommand(llvm::make_unique<FallbackCommand>(JA, *this, Exec, CmdArgs,
4519*0a6a1f1dSLionel Sambuc std::move(CLCommand)));
4520f4a2713aSLionel Sambuc } else {
4521*0a6a1f1dSLionel Sambuc C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
4522f4a2713aSLionel Sambuc }
4523f4a2713aSLionel Sambuc
4524f4a2713aSLionel Sambuc
4525f4a2713aSLionel Sambuc // Handle the debug info splitting at object creation time if we're
4526f4a2713aSLionel Sambuc // creating an object.
4527f4a2713aSLionel Sambuc // TODO: Currently only works on linux with newer objcopy.
4528*0a6a1f1dSLionel Sambuc if (SplitDwarf && !isa<CompileJobAction>(JA) && !isa<BackendJobAction>(JA))
4529f4a2713aSLionel Sambuc SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output, SplitDwarfOut);
4530f4a2713aSLionel Sambuc
4531f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_pg))
4532f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_fomit_frame_pointer))
4533f4a2713aSLionel Sambuc D.Diag(diag::err_drv_argument_not_allowed_with)
4534f4a2713aSLionel Sambuc << "-fomit-frame-pointer" << A->getAsString(Args);
4535f4a2713aSLionel Sambuc
4536f4a2713aSLionel Sambuc // Claim some arguments which clang supports automatically.
4537f4a2713aSLionel Sambuc
4538f4a2713aSLionel Sambuc // -fpch-preprocess is used with gcc to add a special marker in the output to
4539f4a2713aSLionel Sambuc // include the PCH file. Clang's PTH solution is completely transparent, so we
4540f4a2713aSLionel Sambuc // do not need to deal with it at all.
4541f4a2713aSLionel Sambuc Args.ClaimAllArgs(options::OPT_fpch_preprocess);
4542f4a2713aSLionel Sambuc
4543f4a2713aSLionel Sambuc // Claim some arguments which clang doesn't support, but we don't
4544f4a2713aSLionel Sambuc // care to warn the user about.
4545f4a2713aSLionel Sambuc Args.ClaimAllArgs(options::OPT_clang_ignored_f_Group);
4546f4a2713aSLionel Sambuc Args.ClaimAllArgs(options::OPT_clang_ignored_m_Group);
4547f4a2713aSLionel Sambuc
4548f4a2713aSLionel Sambuc // Disable warnings for clang -E -emit-llvm foo.c
4549f4a2713aSLionel Sambuc Args.ClaimAllArgs(options::OPT_emit_llvm);
4550f4a2713aSLionel Sambuc }
4551f4a2713aSLionel Sambuc
4552f4a2713aSLionel Sambuc /// Add options related to the Objective-C runtime/ABI.
4553f4a2713aSLionel Sambuc ///
4554f4a2713aSLionel Sambuc /// Returns true if the runtime is non-fragile.
AddObjCRuntimeArgs(const ArgList & args,ArgStringList & cmdArgs,RewriteKind rewriteKind) const4555f4a2713aSLionel Sambuc ObjCRuntime Clang::AddObjCRuntimeArgs(const ArgList &args,
4556f4a2713aSLionel Sambuc ArgStringList &cmdArgs,
4557f4a2713aSLionel Sambuc RewriteKind rewriteKind) const {
4558f4a2713aSLionel Sambuc // Look for the controlling runtime option.
4559f4a2713aSLionel Sambuc Arg *runtimeArg = args.getLastArg(options::OPT_fnext_runtime,
4560f4a2713aSLionel Sambuc options::OPT_fgnu_runtime,
4561f4a2713aSLionel Sambuc options::OPT_fobjc_runtime_EQ);
4562f4a2713aSLionel Sambuc
4563f4a2713aSLionel Sambuc // Just forward -fobjc-runtime= to the frontend. This supercedes
4564f4a2713aSLionel Sambuc // options about fragility.
4565f4a2713aSLionel Sambuc if (runtimeArg &&
4566f4a2713aSLionel Sambuc runtimeArg->getOption().matches(options::OPT_fobjc_runtime_EQ)) {
4567f4a2713aSLionel Sambuc ObjCRuntime runtime;
4568f4a2713aSLionel Sambuc StringRef value = runtimeArg->getValue();
4569f4a2713aSLionel Sambuc if (runtime.tryParse(value)) {
4570f4a2713aSLionel Sambuc getToolChain().getDriver().Diag(diag::err_drv_unknown_objc_runtime)
4571f4a2713aSLionel Sambuc << value;
4572f4a2713aSLionel Sambuc }
4573f4a2713aSLionel Sambuc
4574f4a2713aSLionel Sambuc runtimeArg->render(args, cmdArgs);
4575f4a2713aSLionel Sambuc return runtime;
4576f4a2713aSLionel Sambuc }
4577f4a2713aSLionel Sambuc
4578f4a2713aSLionel Sambuc // Otherwise, we'll need the ABI "version". Version numbers are
4579f4a2713aSLionel Sambuc // slightly confusing for historical reasons:
4580f4a2713aSLionel Sambuc // 1 - Traditional "fragile" ABI
4581f4a2713aSLionel Sambuc // 2 - Non-fragile ABI, version 1
4582f4a2713aSLionel Sambuc // 3 - Non-fragile ABI, version 2
4583f4a2713aSLionel Sambuc unsigned objcABIVersion = 1;
4584f4a2713aSLionel Sambuc // If -fobjc-abi-version= is present, use that to set the version.
4585f4a2713aSLionel Sambuc if (Arg *abiArg = args.getLastArg(options::OPT_fobjc_abi_version_EQ)) {
4586f4a2713aSLionel Sambuc StringRef value = abiArg->getValue();
4587f4a2713aSLionel Sambuc if (value == "1")
4588f4a2713aSLionel Sambuc objcABIVersion = 1;
4589f4a2713aSLionel Sambuc else if (value == "2")
4590f4a2713aSLionel Sambuc objcABIVersion = 2;
4591f4a2713aSLionel Sambuc else if (value == "3")
4592f4a2713aSLionel Sambuc objcABIVersion = 3;
4593f4a2713aSLionel Sambuc else
4594f4a2713aSLionel Sambuc getToolChain().getDriver().Diag(diag::err_drv_clang_unsupported)
4595f4a2713aSLionel Sambuc << value;
4596f4a2713aSLionel Sambuc } else {
4597f4a2713aSLionel Sambuc // Otherwise, determine if we are using the non-fragile ABI.
4598f4a2713aSLionel Sambuc bool nonFragileABIIsDefault =
4599f4a2713aSLionel Sambuc (rewriteKind == RK_NonFragile ||
4600f4a2713aSLionel Sambuc (rewriteKind == RK_None &&
4601f4a2713aSLionel Sambuc getToolChain().IsObjCNonFragileABIDefault()));
4602f4a2713aSLionel Sambuc if (args.hasFlag(options::OPT_fobjc_nonfragile_abi,
4603f4a2713aSLionel Sambuc options::OPT_fno_objc_nonfragile_abi,
4604f4a2713aSLionel Sambuc nonFragileABIIsDefault)) {
4605f4a2713aSLionel Sambuc // Determine the non-fragile ABI version to use.
4606f4a2713aSLionel Sambuc #ifdef DISABLE_DEFAULT_NONFRAGILEABI_TWO
4607f4a2713aSLionel Sambuc unsigned nonFragileABIVersion = 1;
4608f4a2713aSLionel Sambuc #else
4609f4a2713aSLionel Sambuc unsigned nonFragileABIVersion = 2;
4610f4a2713aSLionel Sambuc #endif
4611f4a2713aSLionel Sambuc
4612f4a2713aSLionel Sambuc if (Arg *abiArg = args.getLastArg(
4613f4a2713aSLionel Sambuc options::OPT_fobjc_nonfragile_abi_version_EQ)) {
4614f4a2713aSLionel Sambuc StringRef value = abiArg->getValue();
4615f4a2713aSLionel Sambuc if (value == "1")
4616f4a2713aSLionel Sambuc nonFragileABIVersion = 1;
4617f4a2713aSLionel Sambuc else if (value == "2")
4618f4a2713aSLionel Sambuc nonFragileABIVersion = 2;
4619f4a2713aSLionel Sambuc else
4620f4a2713aSLionel Sambuc getToolChain().getDriver().Diag(diag::err_drv_clang_unsupported)
4621f4a2713aSLionel Sambuc << value;
4622f4a2713aSLionel Sambuc }
4623f4a2713aSLionel Sambuc
4624f4a2713aSLionel Sambuc objcABIVersion = 1 + nonFragileABIVersion;
4625f4a2713aSLionel Sambuc } else {
4626f4a2713aSLionel Sambuc objcABIVersion = 1;
4627f4a2713aSLionel Sambuc }
4628f4a2713aSLionel Sambuc }
4629f4a2713aSLionel Sambuc
4630f4a2713aSLionel Sambuc // We don't actually care about the ABI version other than whether
4631f4a2713aSLionel Sambuc // it's non-fragile.
4632f4a2713aSLionel Sambuc bool isNonFragile = objcABIVersion != 1;
4633f4a2713aSLionel Sambuc
4634f4a2713aSLionel Sambuc // If we have no runtime argument, ask the toolchain for its default runtime.
4635f4a2713aSLionel Sambuc // However, the rewriter only really supports the Mac runtime, so assume that.
4636f4a2713aSLionel Sambuc ObjCRuntime runtime;
4637f4a2713aSLionel Sambuc if (!runtimeArg) {
4638f4a2713aSLionel Sambuc switch (rewriteKind) {
4639f4a2713aSLionel Sambuc case RK_None:
4640f4a2713aSLionel Sambuc runtime = getToolChain().getDefaultObjCRuntime(isNonFragile);
4641f4a2713aSLionel Sambuc break;
4642f4a2713aSLionel Sambuc case RK_Fragile:
4643f4a2713aSLionel Sambuc runtime = ObjCRuntime(ObjCRuntime::FragileMacOSX, VersionTuple());
4644f4a2713aSLionel Sambuc break;
4645f4a2713aSLionel Sambuc case RK_NonFragile:
4646f4a2713aSLionel Sambuc runtime = ObjCRuntime(ObjCRuntime::MacOSX, VersionTuple());
4647f4a2713aSLionel Sambuc break;
4648f4a2713aSLionel Sambuc }
4649f4a2713aSLionel Sambuc
4650f4a2713aSLionel Sambuc // -fnext-runtime
4651f4a2713aSLionel Sambuc } else if (runtimeArg->getOption().matches(options::OPT_fnext_runtime)) {
4652f4a2713aSLionel Sambuc // On Darwin, make this use the default behavior for the toolchain.
4653f4a2713aSLionel Sambuc if (getToolChain().getTriple().isOSDarwin()) {
4654f4a2713aSLionel Sambuc runtime = getToolChain().getDefaultObjCRuntime(isNonFragile);
4655f4a2713aSLionel Sambuc
4656f4a2713aSLionel Sambuc // Otherwise, build for a generic macosx port.
4657f4a2713aSLionel Sambuc } else {
4658f4a2713aSLionel Sambuc runtime = ObjCRuntime(ObjCRuntime::MacOSX, VersionTuple());
4659f4a2713aSLionel Sambuc }
4660f4a2713aSLionel Sambuc
4661f4a2713aSLionel Sambuc // -fgnu-runtime
4662f4a2713aSLionel Sambuc } else {
4663f4a2713aSLionel Sambuc assert(runtimeArg->getOption().matches(options::OPT_fgnu_runtime));
4664f4a2713aSLionel Sambuc // Legacy behaviour is to target the gnustep runtime if we are i
4665f4a2713aSLionel Sambuc // non-fragile mode or the GCC runtime in fragile mode.
4666f4a2713aSLionel Sambuc if (isNonFragile)
4667f4a2713aSLionel Sambuc runtime = ObjCRuntime(ObjCRuntime::GNUstep, VersionTuple(1,6));
4668f4a2713aSLionel Sambuc else
4669f4a2713aSLionel Sambuc runtime = ObjCRuntime(ObjCRuntime::GCC, VersionTuple());
4670f4a2713aSLionel Sambuc }
4671f4a2713aSLionel Sambuc
4672f4a2713aSLionel Sambuc cmdArgs.push_back(args.MakeArgString(
4673f4a2713aSLionel Sambuc "-fobjc-runtime=" + runtime.getAsString()));
4674f4a2713aSLionel Sambuc return runtime;
4675f4a2713aSLionel Sambuc }
4676f4a2713aSLionel Sambuc
maybeConsumeDash(const std::string & EH,size_t & I)4677*0a6a1f1dSLionel Sambuc static bool maybeConsumeDash(const std::string &EH, size_t &I) {
4678*0a6a1f1dSLionel Sambuc bool HaveDash = (I + 1 < EH.size() && EH[I + 1] == '-');
4679*0a6a1f1dSLionel Sambuc I += HaveDash;
4680*0a6a1f1dSLionel Sambuc return !HaveDash;
4681*0a6a1f1dSLionel Sambuc }
4682*0a6a1f1dSLionel Sambuc
4683*0a6a1f1dSLionel Sambuc struct EHFlags {
EHFlagsEHFlags4684*0a6a1f1dSLionel Sambuc EHFlags() : Synch(false), Asynch(false), NoExceptC(false) {}
4685*0a6a1f1dSLionel Sambuc bool Synch;
4686*0a6a1f1dSLionel Sambuc bool Asynch;
4687*0a6a1f1dSLionel Sambuc bool NoExceptC;
4688*0a6a1f1dSLionel Sambuc };
4689*0a6a1f1dSLionel Sambuc
4690*0a6a1f1dSLionel Sambuc /// /EH controls whether to run destructor cleanups when exceptions are
4691*0a6a1f1dSLionel Sambuc /// thrown. There are three modifiers:
4692*0a6a1f1dSLionel Sambuc /// - s: Cleanup after "synchronous" exceptions, aka C++ exceptions.
4693*0a6a1f1dSLionel Sambuc /// - a: Cleanup after "asynchronous" exceptions, aka structured exceptions.
4694*0a6a1f1dSLionel Sambuc /// The 'a' modifier is unimplemented and fundamentally hard in LLVM IR.
4695*0a6a1f1dSLionel Sambuc /// - c: Assume that extern "C" functions are implicitly noexcept. This
4696*0a6a1f1dSLionel Sambuc /// modifier is an optimization, so we ignore it for now.
4697*0a6a1f1dSLionel Sambuc /// The default is /EHs-c-, meaning cleanups are disabled.
parseClangCLEHFlags(const Driver & D,const ArgList & Args)4698*0a6a1f1dSLionel Sambuc static EHFlags parseClangCLEHFlags(const Driver &D, const ArgList &Args) {
4699*0a6a1f1dSLionel Sambuc EHFlags EH;
4700*0a6a1f1dSLionel Sambuc std::vector<std::string> EHArgs = Args.getAllArgValues(options::OPT__SLASH_EH);
4701*0a6a1f1dSLionel Sambuc for (auto EHVal : EHArgs) {
4702*0a6a1f1dSLionel Sambuc for (size_t I = 0, E = EHVal.size(); I != E; ++I) {
4703*0a6a1f1dSLionel Sambuc switch (EHVal[I]) {
4704*0a6a1f1dSLionel Sambuc case 'a': EH.Asynch = maybeConsumeDash(EHVal, I); continue;
4705*0a6a1f1dSLionel Sambuc case 'c': EH.NoExceptC = maybeConsumeDash(EHVal, I); continue;
4706*0a6a1f1dSLionel Sambuc case 's': EH.Synch = maybeConsumeDash(EHVal, I); continue;
4707*0a6a1f1dSLionel Sambuc default: break;
4708*0a6a1f1dSLionel Sambuc }
4709*0a6a1f1dSLionel Sambuc D.Diag(clang::diag::err_drv_invalid_value) << "/EH" << EHVal;
4710*0a6a1f1dSLionel Sambuc break;
4711*0a6a1f1dSLionel Sambuc }
4712*0a6a1f1dSLionel Sambuc }
4713*0a6a1f1dSLionel Sambuc return EH;
4714*0a6a1f1dSLionel Sambuc }
4715*0a6a1f1dSLionel Sambuc
AddClangCLArgs(const ArgList & Args,ArgStringList & CmdArgs) const4716f4a2713aSLionel Sambuc void Clang::AddClangCLArgs(const ArgList &Args, ArgStringList &CmdArgs) const {
4717f4a2713aSLionel Sambuc unsigned RTOptionID = options::OPT__SLASH_MT;
4718f4a2713aSLionel Sambuc
4719f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT__SLASH_LDd))
4720f4a2713aSLionel Sambuc // The /LDd option implies /MTd. The dependent lib part can be overridden,
4721f4a2713aSLionel Sambuc // but defining _DEBUG is sticky.
4722f4a2713aSLionel Sambuc RTOptionID = options::OPT__SLASH_MTd;
4723f4a2713aSLionel Sambuc
4724f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT__SLASH_M_Group))
4725f4a2713aSLionel Sambuc RTOptionID = A->getOption().getID();
4726f4a2713aSLionel Sambuc
4727f4a2713aSLionel Sambuc switch(RTOptionID) {
4728f4a2713aSLionel Sambuc case options::OPT__SLASH_MD:
4729f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT__SLASH_LDd))
4730f4a2713aSLionel Sambuc CmdArgs.push_back("-D_DEBUG");
4731f4a2713aSLionel Sambuc CmdArgs.push_back("-D_MT");
4732f4a2713aSLionel Sambuc CmdArgs.push_back("-D_DLL");
4733f4a2713aSLionel Sambuc CmdArgs.push_back("--dependent-lib=msvcrt");
4734f4a2713aSLionel Sambuc break;
4735f4a2713aSLionel Sambuc case options::OPT__SLASH_MDd:
4736f4a2713aSLionel Sambuc CmdArgs.push_back("-D_DEBUG");
4737f4a2713aSLionel Sambuc CmdArgs.push_back("-D_MT");
4738f4a2713aSLionel Sambuc CmdArgs.push_back("-D_DLL");
4739f4a2713aSLionel Sambuc CmdArgs.push_back("--dependent-lib=msvcrtd");
4740f4a2713aSLionel Sambuc break;
4741f4a2713aSLionel Sambuc case options::OPT__SLASH_MT:
4742f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT__SLASH_LDd))
4743f4a2713aSLionel Sambuc CmdArgs.push_back("-D_DEBUG");
4744f4a2713aSLionel Sambuc CmdArgs.push_back("-D_MT");
4745f4a2713aSLionel Sambuc CmdArgs.push_back("--dependent-lib=libcmt");
4746f4a2713aSLionel Sambuc break;
4747f4a2713aSLionel Sambuc case options::OPT__SLASH_MTd:
4748f4a2713aSLionel Sambuc CmdArgs.push_back("-D_DEBUG");
4749f4a2713aSLionel Sambuc CmdArgs.push_back("-D_MT");
4750f4a2713aSLionel Sambuc CmdArgs.push_back("--dependent-lib=libcmtd");
4751f4a2713aSLionel Sambuc break;
4752f4a2713aSLionel Sambuc default:
4753f4a2713aSLionel Sambuc llvm_unreachable("Unexpected option ID.");
4754f4a2713aSLionel Sambuc }
4755f4a2713aSLionel Sambuc
4756f4a2713aSLionel Sambuc // This provides POSIX compatibility (maps 'open' to '_open'), which most
4757f4a2713aSLionel Sambuc // users want. The /Za flag to cl.exe turns this off, but it's not
4758f4a2713aSLionel Sambuc // implemented in clang.
4759f4a2713aSLionel Sambuc CmdArgs.push_back("--dependent-lib=oldnames");
4760f4a2713aSLionel Sambuc
4761*0a6a1f1dSLionel Sambuc // Both /showIncludes and /E (and /EP) write to stdout. Allowing both
4762*0a6a1f1dSLionel Sambuc // would produce interleaved output, so ignore /showIncludes in such cases.
4763*0a6a1f1dSLionel Sambuc if (!Args.hasArg(options::OPT_E) && !Args.hasArg(options::OPT__SLASH_EP))
4764f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_show_includes))
4765f4a2713aSLionel Sambuc A->render(Args, CmdArgs);
4766f4a2713aSLionel Sambuc
4767*0a6a1f1dSLionel Sambuc // This controls whether or not we emit RTTI data for polymorphic types.
4768*0a6a1f1dSLionel Sambuc if (Args.hasFlag(options::OPT__SLASH_GR_, options::OPT__SLASH_GR,
4769*0a6a1f1dSLionel Sambuc /*default=*/false))
4770*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-fno-rtti-data");
4771*0a6a1f1dSLionel Sambuc
4772*0a6a1f1dSLionel Sambuc const Driver &D = getToolChain().getDriver();
4773*0a6a1f1dSLionel Sambuc EHFlags EH = parseClangCLEHFlags(D, Args);
4774*0a6a1f1dSLionel Sambuc // FIXME: Do something with NoExceptC.
4775*0a6a1f1dSLionel Sambuc if (EH.Synch || EH.Asynch) {
4776*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-fexceptions");
4777*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-fcxx-exceptions");
4778*0a6a1f1dSLionel Sambuc }
4779*0a6a1f1dSLionel Sambuc
4780*0a6a1f1dSLionel Sambuc // /EP should expand to -E -P.
4781*0a6a1f1dSLionel Sambuc if (Args.hasArg(options::OPT__SLASH_EP)) {
4782*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-E");
4783*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-P");
4784*0a6a1f1dSLionel Sambuc }
4785*0a6a1f1dSLionel Sambuc
4786*0a6a1f1dSLionel Sambuc Arg *MostGeneralArg = Args.getLastArg(options::OPT__SLASH_vmg);
4787*0a6a1f1dSLionel Sambuc Arg *BestCaseArg = Args.getLastArg(options::OPT__SLASH_vmb);
4788*0a6a1f1dSLionel Sambuc if (MostGeneralArg && BestCaseArg)
4789*0a6a1f1dSLionel Sambuc D.Diag(clang::diag::err_drv_argument_not_allowed_with)
4790*0a6a1f1dSLionel Sambuc << MostGeneralArg->getAsString(Args) << BestCaseArg->getAsString(Args);
4791*0a6a1f1dSLionel Sambuc
4792*0a6a1f1dSLionel Sambuc if (MostGeneralArg) {
4793*0a6a1f1dSLionel Sambuc Arg *SingleArg = Args.getLastArg(options::OPT__SLASH_vms);
4794*0a6a1f1dSLionel Sambuc Arg *MultipleArg = Args.getLastArg(options::OPT__SLASH_vmm);
4795*0a6a1f1dSLionel Sambuc Arg *VirtualArg = Args.getLastArg(options::OPT__SLASH_vmv);
4796*0a6a1f1dSLionel Sambuc
4797*0a6a1f1dSLionel Sambuc Arg *FirstConflict = SingleArg ? SingleArg : MultipleArg;
4798*0a6a1f1dSLionel Sambuc Arg *SecondConflict = VirtualArg ? VirtualArg : MultipleArg;
4799*0a6a1f1dSLionel Sambuc if (FirstConflict && SecondConflict && FirstConflict != SecondConflict)
4800*0a6a1f1dSLionel Sambuc D.Diag(clang::diag::err_drv_argument_not_allowed_with)
4801*0a6a1f1dSLionel Sambuc << FirstConflict->getAsString(Args)
4802*0a6a1f1dSLionel Sambuc << SecondConflict->getAsString(Args);
4803*0a6a1f1dSLionel Sambuc
4804*0a6a1f1dSLionel Sambuc if (SingleArg)
4805*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-fms-memptr-rep=single");
4806*0a6a1f1dSLionel Sambuc else if (MultipleArg)
4807*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-fms-memptr-rep=multiple");
4808*0a6a1f1dSLionel Sambuc else
4809*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-fms-memptr-rep=virtual");
4810*0a6a1f1dSLionel Sambuc }
4811*0a6a1f1dSLionel Sambuc
4812*0a6a1f1dSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_vtordisp_mode_EQ))
4813*0a6a1f1dSLionel Sambuc A->render(Args, CmdArgs);
4814*0a6a1f1dSLionel Sambuc
4815f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_fdiagnostics_format_EQ)) {
4816f4a2713aSLionel Sambuc CmdArgs.push_back("-fdiagnostics-format");
4817f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT__SLASH_fallback))
4818f4a2713aSLionel Sambuc CmdArgs.push_back("msvc-fallback");
4819f4a2713aSLionel Sambuc else
4820f4a2713aSLionel Sambuc CmdArgs.push_back("msvc");
4821f4a2713aSLionel Sambuc }
4822f4a2713aSLionel Sambuc }
4823f4a2713aSLionel Sambuc
getCLFallback() const4824*0a6a1f1dSLionel Sambuc visualstudio::Compile *Clang::getCLFallback() const {
4825*0a6a1f1dSLionel Sambuc if (!CLFallback)
4826*0a6a1f1dSLionel Sambuc CLFallback.reset(new visualstudio::Compile(getToolChain()));
4827*0a6a1f1dSLionel Sambuc return CLFallback.get();
4828*0a6a1f1dSLionel Sambuc }
4829*0a6a1f1dSLionel Sambuc
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const4830f4a2713aSLionel Sambuc void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
4831f4a2713aSLionel Sambuc const InputInfo &Output,
4832f4a2713aSLionel Sambuc const InputInfoList &Inputs,
4833f4a2713aSLionel Sambuc const ArgList &Args,
4834f4a2713aSLionel Sambuc const char *LinkingOutput) const {
4835f4a2713aSLionel Sambuc ArgStringList CmdArgs;
4836f4a2713aSLionel Sambuc
4837f4a2713aSLionel Sambuc assert(Inputs.size() == 1 && "Unexpected number of inputs.");
4838f4a2713aSLionel Sambuc const InputInfo &Input = Inputs[0];
4839f4a2713aSLionel Sambuc
4840f4a2713aSLionel Sambuc // Don't warn about "clang -w -c foo.s"
4841f4a2713aSLionel Sambuc Args.ClaimAllArgs(options::OPT_w);
4842f4a2713aSLionel Sambuc // and "clang -emit-llvm -c foo.s"
4843f4a2713aSLionel Sambuc Args.ClaimAllArgs(options::OPT_emit_llvm);
4844f4a2713aSLionel Sambuc
4845*0a6a1f1dSLionel Sambuc claimNoWarnArgs(Args);
4846*0a6a1f1dSLionel Sambuc
4847f4a2713aSLionel Sambuc // Invoke ourselves in -cc1as mode.
4848f4a2713aSLionel Sambuc //
4849f4a2713aSLionel Sambuc // FIXME: Implement custom jobs for internal actions.
4850f4a2713aSLionel Sambuc CmdArgs.push_back("-cc1as");
4851f4a2713aSLionel Sambuc
4852f4a2713aSLionel Sambuc // Add the "effective" target triple.
4853f4a2713aSLionel Sambuc CmdArgs.push_back("-triple");
4854f4a2713aSLionel Sambuc std::string TripleStr =
4855f4a2713aSLionel Sambuc getToolChain().ComputeEffectiveClangTriple(Args, Input.getType());
4856f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(TripleStr));
4857f4a2713aSLionel Sambuc
4858f4a2713aSLionel Sambuc // Set the output mode, we currently only expect to be used as a real
4859f4a2713aSLionel Sambuc // assembler.
4860f4a2713aSLionel Sambuc CmdArgs.push_back("-filetype");
4861f4a2713aSLionel Sambuc CmdArgs.push_back("obj");
4862f4a2713aSLionel Sambuc
4863f4a2713aSLionel Sambuc // Set the main file name, so that debug info works even with
4864f4a2713aSLionel Sambuc // -save-temps or preprocessed assembly.
4865f4a2713aSLionel Sambuc CmdArgs.push_back("-main-file-name");
4866f4a2713aSLionel Sambuc CmdArgs.push_back(Clang::getBaseInputName(Args, Inputs));
4867f4a2713aSLionel Sambuc
4868f4a2713aSLionel Sambuc // Add the target cpu
4869f4a2713aSLionel Sambuc const llvm::Triple &Triple = getToolChain().getTriple();
4870f4a2713aSLionel Sambuc std::string CPU = getCPUName(Args, Triple);
4871f4a2713aSLionel Sambuc if (!CPU.empty()) {
4872f4a2713aSLionel Sambuc CmdArgs.push_back("-target-cpu");
4873f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(CPU));
4874f4a2713aSLionel Sambuc }
4875f4a2713aSLionel Sambuc
4876f4a2713aSLionel Sambuc // Add the target features
4877f4a2713aSLionel Sambuc const Driver &D = getToolChain().getDriver();
4878*0a6a1f1dSLionel Sambuc getTargetFeatures(D, Triple, Args, CmdArgs, true);
4879f4a2713aSLionel Sambuc
4880f4a2713aSLionel Sambuc // Ignore explicit -force_cpusubtype_ALL option.
4881f4a2713aSLionel Sambuc (void) Args.hasArg(options::OPT_force__cpusubtype__ALL);
4882f4a2713aSLionel Sambuc
4883f4a2713aSLionel Sambuc // Determine the original source input.
4884f4a2713aSLionel Sambuc const Action *SourceAction = &JA;
4885f4a2713aSLionel Sambuc while (SourceAction->getKind() != Action::InputClass) {
4886f4a2713aSLionel Sambuc assert(!SourceAction->getInputs().empty() && "unexpected root action!");
4887f4a2713aSLionel Sambuc SourceAction = SourceAction->getInputs()[0];
4888f4a2713aSLionel Sambuc }
4889f4a2713aSLionel Sambuc
4890f4a2713aSLionel Sambuc // Forward -g and handle debug info related flags, assuming we are dealing
4891f4a2713aSLionel Sambuc // with an actual assembly file.
4892f4a2713aSLionel Sambuc if (SourceAction->getType() == types::TY_Asm ||
4893f4a2713aSLionel Sambuc SourceAction->getType() == types::TY_PP_Asm) {
4894f4a2713aSLionel Sambuc Args.ClaimAllArgs(options::OPT_g_Group);
4895f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_g_Group))
4896f4a2713aSLionel Sambuc if (!A->getOption().matches(options::OPT_g0))
4897f4a2713aSLionel Sambuc CmdArgs.push_back("-g");
4898f4a2713aSLionel Sambuc
4899*0a6a1f1dSLionel Sambuc if (Args.hasArg(options::OPT_gdwarf_2))
4900*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-gdwarf-2");
4901*0a6a1f1dSLionel Sambuc if (Args.hasArg(options::OPT_gdwarf_3))
4902*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-gdwarf-3");
4903*0a6a1f1dSLionel Sambuc if (Args.hasArg(options::OPT_gdwarf_4))
4904*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-gdwarf-4");
4905*0a6a1f1dSLionel Sambuc
4906f4a2713aSLionel Sambuc // Add the -fdebug-compilation-dir flag if needed.
4907f4a2713aSLionel Sambuc addDebugCompDirArg(Args, CmdArgs);
4908f4a2713aSLionel Sambuc
4909f4a2713aSLionel Sambuc // Set the AT_producer to the clang version when using the integrated
4910f4a2713aSLionel Sambuc // assembler on assembly source files.
4911f4a2713aSLionel Sambuc CmdArgs.push_back("-dwarf-debug-producer");
4912f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(getClangFullVersion()));
4913f4a2713aSLionel Sambuc }
4914f4a2713aSLionel Sambuc
4915f4a2713aSLionel Sambuc // Optionally embed the -cc1as level arguments into the debug info, for build
4916f4a2713aSLionel Sambuc // analysis.
4917f4a2713aSLionel Sambuc if (getToolChain().UseDwarfDebugFlags()) {
4918f4a2713aSLionel Sambuc ArgStringList OriginalArgs;
4919*0a6a1f1dSLionel Sambuc for (const auto &Arg : Args)
4920*0a6a1f1dSLionel Sambuc Arg->render(Args, OriginalArgs);
4921f4a2713aSLionel Sambuc
4922f4a2713aSLionel Sambuc SmallString<256> Flags;
4923f4a2713aSLionel Sambuc const char *Exec = getToolChain().getDriver().getClangProgramPath();
4924f4a2713aSLionel Sambuc Flags += Exec;
4925f4a2713aSLionel Sambuc for (unsigned i = 0, e = OriginalArgs.size(); i != e; ++i) {
4926*0a6a1f1dSLionel Sambuc SmallString<128> EscapedArg;
4927*0a6a1f1dSLionel Sambuc EscapeSpacesAndBackslashes(OriginalArgs[i], EscapedArg);
4928f4a2713aSLionel Sambuc Flags += " ";
4929*0a6a1f1dSLionel Sambuc Flags += EscapedArg;
4930f4a2713aSLionel Sambuc }
4931f4a2713aSLionel Sambuc CmdArgs.push_back("-dwarf-debug-flags");
4932f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(Flags.str()));
4933f4a2713aSLionel Sambuc }
4934f4a2713aSLionel Sambuc
4935f4a2713aSLionel Sambuc // FIXME: Add -static support, once we have it.
4936f4a2713aSLionel Sambuc
4937*0a6a1f1dSLionel Sambuc // Consume all the warning flags. Usually this would be handled more
4938*0a6a1f1dSLionel Sambuc // gracefully by -cc1 (warning about unknown warning flags, etc) but -cc1as
4939*0a6a1f1dSLionel Sambuc // doesn't handle that so rather than warning about unused flags that are
4940*0a6a1f1dSLionel Sambuc // actually used, we'll lie by omission instead.
4941*0a6a1f1dSLionel Sambuc // FIXME: Stop lying and consume only the appropriate driver flags
4942*0a6a1f1dSLionel Sambuc for (arg_iterator it = Args.filtered_begin(options::OPT_W_Group),
4943*0a6a1f1dSLionel Sambuc ie = Args.filtered_end();
4944*0a6a1f1dSLionel Sambuc it != ie; ++it)
4945*0a6a1f1dSLionel Sambuc (*it)->claim();
4946*0a6a1f1dSLionel Sambuc
4947f4a2713aSLionel Sambuc CollectArgsForIntegratedAssembler(C, Args, CmdArgs,
4948f4a2713aSLionel Sambuc getToolChain().getDriver());
4949f4a2713aSLionel Sambuc
4950f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_mllvm);
4951f4a2713aSLionel Sambuc
4952f4a2713aSLionel Sambuc assert(Output.isFilename() && "Unexpected lipo output.");
4953f4a2713aSLionel Sambuc CmdArgs.push_back("-o");
4954f4a2713aSLionel Sambuc CmdArgs.push_back(Output.getFilename());
4955f4a2713aSLionel Sambuc
4956f4a2713aSLionel Sambuc assert(Input.isFilename() && "Invalid input.");
4957f4a2713aSLionel Sambuc CmdArgs.push_back(Input.getFilename());
4958f4a2713aSLionel Sambuc
4959f4a2713aSLionel Sambuc const char *Exec = getToolChain().getDriver().getClangProgramPath();
4960*0a6a1f1dSLionel Sambuc C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
4961f4a2713aSLionel Sambuc
4962f4a2713aSLionel Sambuc // Handle the debug info splitting at object creation time if we're
4963f4a2713aSLionel Sambuc // creating an object.
4964f4a2713aSLionel Sambuc // TODO: Currently only works on linux with newer objcopy.
4965f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_gsplit_dwarf) &&
4966f4a2713aSLionel Sambuc getToolChain().getTriple().isOSLinux())
4967f4a2713aSLionel Sambuc SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output,
4968f4a2713aSLionel Sambuc SplitDebugName(Args, Inputs));
4969f4a2713aSLionel Sambuc }
4970f4a2713aSLionel Sambuc
anchor()4971*0a6a1f1dSLionel Sambuc void GnuTool::anchor() {}
4972*0a6a1f1dSLionel Sambuc
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const4973f4a2713aSLionel Sambuc void gcc::Common::ConstructJob(Compilation &C, const JobAction &JA,
4974f4a2713aSLionel Sambuc const InputInfo &Output,
4975f4a2713aSLionel Sambuc const InputInfoList &Inputs,
4976f4a2713aSLionel Sambuc const ArgList &Args,
4977f4a2713aSLionel Sambuc const char *LinkingOutput) const {
4978f4a2713aSLionel Sambuc const Driver &D = getToolChain().getDriver();
4979f4a2713aSLionel Sambuc ArgStringList CmdArgs;
4980f4a2713aSLionel Sambuc
4981*0a6a1f1dSLionel Sambuc for (const auto &A : Args) {
4982f4a2713aSLionel Sambuc if (forwardToGCC(A->getOption())) {
4983f4a2713aSLionel Sambuc // Don't forward any -g arguments to assembly steps.
4984f4a2713aSLionel Sambuc if (isa<AssembleJobAction>(JA) &&
4985f4a2713aSLionel Sambuc A->getOption().matches(options::OPT_g_Group))
4986f4a2713aSLionel Sambuc continue;
4987f4a2713aSLionel Sambuc
4988f4a2713aSLionel Sambuc // Don't forward any -W arguments to assembly and link steps.
4989f4a2713aSLionel Sambuc if ((isa<AssembleJobAction>(JA) || isa<LinkJobAction>(JA)) &&
4990f4a2713aSLionel Sambuc A->getOption().matches(options::OPT_W_Group))
4991f4a2713aSLionel Sambuc continue;
4992f4a2713aSLionel Sambuc
4993f4a2713aSLionel Sambuc // It is unfortunate that we have to claim here, as this means
4994f4a2713aSLionel Sambuc // we will basically never report anything interesting for
4995f4a2713aSLionel Sambuc // platforms using a generic gcc, even if we are just using gcc
4996f4a2713aSLionel Sambuc // to get to the assembler.
4997f4a2713aSLionel Sambuc A->claim();
4998f4a2713aSLionel Sambuc A->render(Args, CmdArgs);
4999f4a2713aSLionel Sambuc }
5000f4a2713aSLionel Sambuc }
5001f4a2713aSLionel Sambuc
5002f4a2713aSLionel Sambuc RenderExtraToolArgs(JA, CmdArgs);
5003f4a2713aSLionel Sambuc
5004f4a2713aSLionel Sambuc // If using a driver driver, force the arch.
5005f4a2713aSLionel Sambuc if (getToolChain().getTriple().isOSDarwin()) {
5006f4a2713aSLionel Sambuc CmdArgs.push_back("-arch");
5007*0a6a1f1dSLionel Sambuc CmdArgs.push_back(
5008*0a6a1f1dSLionel Sambuc Args.MakeArgString(getToolChain().getDefaultUniversalArchName()));
5009f4a2713aSLionel Sambuc }
5010f4a2713aSLionel Sambuc
5011f4a2713aSLionel Sambuc // Try to force gcc to match the tool chain we want, if we recognize
5012f4a2713aSLionel Sambuc // the arch.
5013f4a2713aSLionel Sambuc //
5014f4a2713aSLionel Sambuc // FIXME: The triple class should directly provide the information we want
5015f4a2713aSLionel Sambuc // here.
5016*0a6a1f1dSLionel Sambuc llvm::Triple::ArchType Arch = getToolChain().getArch();
5017f4a2713aSLionel Sambuc if (Arch == llvm::Triple::x86 || Arch == llvm::Triple::ppc)
5018f4a2713aSLionel Sambuc CmdArgs.push_back("-m32");
5019f4a2713aSLionel Sambuc else if (Arch == llvm::Triple::x86_64 || Arch == llvm::Triple::ppc64 ||
5020f4a2713aSLionel Sambuc Arch == llvm::Triple::ppc64le)
5021f4a2713aSLionel Sambuc CmdArgs.push_back("-m64");
5022f4a2713aSLionel Sambuc
5023f4a2713aSLionel Sambuc if (Output.isFilename()) {
5024f4a2713aSLionel Sambuc CmdArgs.push_back("-o");
5025f4a2713aSLionel Sambuc CmdArgs.push_back(Output.getFilename());
5026f4a2713aSLionel Sambuc } else {
5027f4a2713aSLionel Sambuc assert(Output.isNothing() && "Unexpected output");
5028f4a2713aSLionel Sambuc CmdArgs.push_back("-fsyntax-only");
5029f4a2713aSLionel Sambuc }
5030f4a2713aSLionel Sambuc
5031f4a2713aSLionel Sambuc Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
5032f4a2713aSLionel Sambuc options::OPT_Xassembler);
5033f4a2713aSLionel Sambuc
5034f4a2713aSLionel Sambuc // Only pass -x if gcc will understand it; otherwise hope gcc
5035f4a2713aSLionel Sambuc // understands the suffix correctly. The main use case this would go
5036f4a2713aSLionel Sambuc // wrong in is for linker inputs if they happened to have an odd
5037f4a2713aSLionel Sambuc // suffix; really the only way to get this to happen is a command
5038f4a2713aSLionel Sambuc // like '-x foobar a.c' which will treat a.c like a linker input.
5039f4a2713aSLionel Sambuc //
5040f4a2713aSLionel Sambuc // FIXME: For the linker case specifically, can we safely convert
5041f4a2713aSLionel Sambuc // inputs into '-Wl,' options?
5042*0a6a1f1dSLionel Sambuc for (const auto &II : Inputs) {
5043f4a2713aSLionel Sambuc // Don't try to pass LLVM or AST inputs to a generic gcc.
5044f4a2713aSLionel Sambuc if (II.getType() == types::TY_LLVM_IR || II.getType() == types::TY_LTO_IR ||
5045f4a2713aSLionel Sambuc II.getType() == types::TY_LLVM_BC || II.getType() == types::TY_LTO_BC)
5046f4a2713aSLionel Sambuc D.Diag(diag::err_drv_no_linker_llvm_support)
5047f4a2713aSLionel Sambuc << getToolChain().getTripleString();
5048f4a2713aSLionel Sambuc else if (II.getType() == types::TY_AST)
5049f4a2713aSLionel Sambuc D.Diag(diag::err_drv_no_ast_support)
5050f4a2713aSLionel Sambuc << getToolChain().getTripleString();
5051f4a2713aSLionel Sambuc else if (II.getType() == types::TY_ModuleFile)
5052f4a2713aSLionel Sambuc D.Diag(diag::err_drv_no_module_support)
5053f4a2713aSLionel Sambuc << getToolChain().getTripleString();
5054f4a2713aSLionel Sambuc
5055f4a2713aSLionel Sambuc if (types::canTypeBeUserSpecified(II.getType())) {
5056f4a2713aSLionel Sambuc CmdArgs.push_back("-x");
5057f4a2713aSLionel Sambuc CmdArgs.push_back(types::getTypeName(II.getType()));
5058f4a2713aSLionel Sambuc }
5059f4a2713aSLionel Sambuc
5060f4a2713aSLionel Sambuc if (II.isFilename())
5061f4a2713aSLionel Sambuc CmdArgs.push_back(II.getFilename());
5062f4a2713aSLionel Sambuc else {
5063f4a2713aSLionel Sambuc const Arg &A = II.getInputArg();
5064f4a2713aSLionel Sambuc
5065f4a2713aSLionel Sambuc // Reverse translate some rewritten options.
5066f4a2713aSLionel Sambuc if (A.getOption().matches(options::OPT_Z_reserved_lib_stdcxx)) {
5067f4a2713aSLionel Sambuc CmdArgs.push_back("-lstdc++");
5068f4a2713aSLionel Sambuc continue;
5069f4a2713aSLionel Sambuc }
5070f4a2713aSLionel Sambuc
5071f4a2713aSLionel Sambuc // Don't render as input, we need gcc to do the translations.
5072f4a2713aSLionel Sambuc A.render(Args, CmdArgs);
5073f4a2713aSLionel Sambuc }
5074f4a2713aSLionel Sambuc }
5075f4a2713aSLionel Sambuc
5076f4a2713aSLionel Sambuc const std::string customGCCName = D.getCCCGenericGCCName();
5077f4a2713aSLionel Sambuc const char *GCCName;
5078f4a2713aSLionel Sambuc if (!customGCCName.empty())
5079f4a2713aSLionel Sambuc GCCName = customGCCName.c_str();
5080f4a2713aSLionel Sambuc else if (D.CCCIsCXX()) {
5081f4a2713aSLionel Sambuc GCCName = "g++";
5082f4a2713aSLionel Sambuc } else
5083f4a2713aSLionel Sambuc GCCName = "gcc";
5084f4a2713aSLionel Sambuc
5085f4a2713aSLionel Sambuc const char *Exec =
5086f4a2713aSLionel Sambuc Args.MakeArgString(getToolChain().GetProgramPath(GCCName));
5087*0a6a1f1dSLionel Sambuc C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
5088f4a2713aSLionel Sambuc }
5089f4a2713aSLionel Sambuc
RenderExtraToolArgs(const JobAction & JA,ArgStringList & CmdArgs) const5090f4a2713aSLionel Sambuc void gcc::Preprocess::RenderExtraToolArgs(const JobAction &JA,
5091f4a2713aSLionel Sambuc ArgStringList &CmdArgs) const {
5092f4a2713aSLionel Sambuc CmdArgs.push_back("-E");
5093f4a2713aSLionel Sambuc }
5094f4a2713aSLionel Sambuc
RenderExtraToolArgs(const JobAction & JA,ArgStringList & CmdArgs) const5095f4a2713aSLionel Sambuc void gcc::Compile::RenderExtraToolArgs(const JobAction &JA,
5096f4a2713aSLionel Sambuc ArgStringList &CmdArgs) const {
5097f4a2713aSLionel Sambuc const Driver &D = getToolChain().getDriver();
5098f4a2713aSLionel Sambuc
5099f4a2713aSLionel Sambuc // If -flto, etc. are present then make sure not to force assembly output.
5100f4a2713aSLionel Sambuc if (JA.getType() == types::TY_LLVM_IR || JA.getType() == types::TY_LTO_IR ||
5101f4a2713aSLionel Sambuc JA.getType() == types::TY_LLVM_BC || JA.getType() == types::TY_LTO_BC)
5102f4a2713aSLionel Sambuc CmdArgs.push_back("-c");
5103f4a2713aSLionel Sambuc else {
5104f4a2713aSLionel Sambuc if (JA.getType() != types::TY_PP_Asm)
5105f4a2713aSLionel Sambuc D.Diag(diag::err_drv_invalid_gcc_output_type)
5106f4a2713aSLionel Sambuc << getTypeName(JA.getType());
5107f4a2713aSLionel Sambuc
5108f4a2713aSLionel Sambuc CmdArgs.push_back("-S");
5109f4a2713aSLionel Sambuc }
5110f4a2713aSLionel Sambuc }
5111f4a2713aSLionel Sambuc
RenderExtraToolArgs(const JobAction & JA,ArgStringList & CmdArgs) const5112f4a2713aSLionel Sambuc void gcc::Link::RenderExtraToolArgs(const JobAction &JA,
5113f4a2713aSLionel Sambuc ArgStringList &CmdArgs) const {
5114f4a2713aSLionel Sambuc // The types are (hopefully) good enough.
5115f4a2713aSLionel Sambuc }
5116f4a2713aSLionel Sambuc
5117f4a2713aSLionel Sambuc // Hexagon tools start.
RenderExtraToolArgs(const JobAction & JA,ArgStringList & CmdArgs) const5118f4a2713aSLionel Sambuc void hexagon::Assemble::RenderExtraToolArgs(const JobAction &JA,
5119f4a2713aSLionel Sambuc ArgStringList &CmdArgs) const {
5120f4a2713aSLionel Sambuc
5121f4a2713aSLionel Sambuc }
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const5122f4a2713aSLionel Sambuc void hexagon::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
5123f4a2713aSLionel Sambuc const InputInfo &Output,
5124f4a2713aSLionel Sambuc const InputInfoList &Inputs,
5125f4a2713aSLionel Sambuc const ArgList &Args,
5126f4a2713aSLionel Sambuc const char *LinkingOutput) const {
5127*0a6a1f1dSLionel Sambuc claimNoWarnArgs(Args);
5128f4a2713aSLionel Sambuc
5129f4a2713aSLionel Sambuc const Driver &D = getToolChain().getDriver();
5130f4a2713aSLionel Sambuc ArgStringList CmdArgs;
5131f4a2713aSLionel Sambuc
5132f4a2713aSLionel Sambuc std::string MarchString = "-march=";
5133f4a2713aSLionel Sambuc MarchString += toolchains::Hexagon_TC::GetTargetCPU(Args);
5134f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(MarchString));
5135f4a2713aSLionel Sambuc
5136f4a2713aSLionel Sambuc RenderExtraToolArgs(JA, CmdArgs);
5137f4a2713aSLionel Sambuc
5138f4a2713aSLionel Sambuc if (Output.isFilename()) {
5139f4a2713aSLionel Sambuc CmdArgs.push_back("-o");
5140f4a2713aSLionel Sambuc CmdArgs.push_back(Output.getFilename());
5141f4a2713aSLionel Sambuc } else {
5142f4a2713aSLionel Sambuc assert(Output.isNothing() && "Unexpected output");
5143f4a2713aSLionel Sambuc CmdArgs.push_back("-fsyntax-only");
5144f4a2713aSLionel Sambuc }
5145f4a2713aSLionel Sambuc
5146f4a2713aSLionel Sambuc std::string SmallDataThreshold = GetHexagonSmallDataThresholdValue(Args);
5147f4a2713aSLionel Sambuc if (!SmallDataThreshold.empty())
5148f4a2713aSLionel Sambuc CmdArgs.push_back(
5149f4a2713aSLionel Sambuc Args.MakeArgString(std::string("-G") + SmallDataThreshold));
5150f4a2713aSLionel Sambuc
5151f4a2713aSLionel Sambuc Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
5152f4a2713aSLionel Sambuc options::OPT_Xassembler);
5153f4a2713aSLionel Sambuc
5154f4a2713aSLionel Sambuc // Only pass -x if gcc will understand it; otherwise hope gcc
5155f4a2713aSLionel Sambuc // understands the suffix correctly. The main use case this would go
5156f4a2713aSLionel Sambuc // wrong in is for linker inputs if they happened to have an odd
5157f4a2713aSLionel Sambuc // suffix; really the only way to get this to happen is a command
5158f4a2713aSLionel Sambuc // like '-x foobar a.c' which will treat a.c like a linker input.
5159f4a2713aSLionel Sambuc //
5160f4a2713aSLionel Sambuc // FIXME: For the linker case specifically, can we safely convert
5161f4a2713aSLionel Sambuc // inputs into '-Wl,' options?
5162*0a6a1f1dSLionel Sambuc for (const auto &II : Inputs) {
5163f4a2713aSLionel Sambuc // Don't try to pass LLVM or AST inputs to a generic gcc.
5164f4a2713aSLionel Sambuc if (II.getType() == types::TY_LLVM_IR || II.getType() == types::TY_LTO_IR ||
5165f4a2713aSLionel Sambuc II.getType() == types::TY_LLVM_BC || II.getType() == types::TY_LTO_BC)
5166f4a2713aSLionel Sambuc D.Diag(clang::diag::err_drv_no_linker_llvm_support)
5167f4a2713aSLionel Sambuc << getToolChain().getTripleString();
5168f4a2713aSLionel Sambuc else if (II.getType() == types::TY_AST)
5169f4a2713aSLionel Sambuc D.Diag(clang::diag::err_drv_no_ast_support)
5170f4a2713aSLionel Sambuc << getToolChain().getTripleString();
5171f4a2713aSLionel Sambuc else if (II.getType() == types::TY_ModuleFile)
5172f4a2713aSLionel Sambuc D.Diag(diag::err_drv_no_module_support)
5173f4a2713aSLionel Sambuc << getToolChain().getTripleString();
5174f4a2713aSLionel Sambuc
5175f4a2713aSLionel Sambuc if (II.isFilename())
5176f4a2713aSLionel Sambuc CmdArgs.push_back(II.getFilename());
5177f4a2713aSLionel Sambuc else
5178f4a2713aSLionel Sambuc // Don't render as input, we need gcc to do the translations. FIXME: Pranav: What is this ?
5179f4a2713aSLionel Sambuc II.getInputArg().render(Args, CmdArgs);
5180f4a2713aSLionel Sambuc }
5181f4a2713aSLionel Sambuc
5182f4a2713aSLionel Sambuc const char *GCCName = "hexagon-as";
5183*0a6a1f1dSLionel Sambuc const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath(GCCName));
5184*0a6a1f1dSLionel Sambuc C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
5185f4a2713aSLionel Sambuc }
5186*0a6a1f1dSLionel Sambuc
RenderExtraToolArgs(const JobAction & JA,ArgStringList & CmdArgs) const5187f4a2713aSLionel Sambuc void hexagon::Link::RenderExtraToolArgs(const JobAction &JA,
5188f4a2713aSLionel Sambuc ArgStringList &CmdArgs) const {
5189f4a2713aSLionel Sambuc // The types are (hopefully) good enough.
5190f4a2713aSLionel Sambuc }
5191f4a2713aSLionel Sambuc
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const5192f4a2713aSLionel Sambuc void hexagon::Link::ConstructJob(Compilation &C, const JobAction &JA,
5193f4a2713aSLionel Sambuc const InputInfo &Output,
5194f4a2713aSLionel Sambuc const InputInfoList &Inputs,
5195f4a2713aSLionel Sambuc const ArgList &Args,
5196f4a2713aSLionel Sambuc const char *LinkingOutput) const {
5197f4a2713aSLionel Sambuc
5198f4a2713aSLionel Sambuc const toolchains::Hexagon_TC& ToolChain =
5199f4a2713aSLionel Sambuc static_cast<const toolchains::Hexagon_TC&>(getToolChain());
5200f4a2713aSLionel Sambuc const Driver &D = ToolChain.getDriver();
5201f4a2713aSLionel Sambuc
5202f4a2713aSLionel Sambuc ArgStringList CmdArgs;
5203f4a2713aSLionel Sambuc
5204f4a2713aSLionel Sambuc //----------------------------------------------------------------------------
5205f4a2713aSLionel Sambuc //
5206f4a2713aSLionel Sambuc //----------------------------------------------------------------------------
5207f4a2713aSLionel Sambuc bool hasStaticArg = Args.hasArg(options::OPT_static);
5208f4a2713aSLionel Sambuc bool buildingLib = Args.hasArg(options::OPT_shared);
5209f4a2713aSLionel Sambuc bool buildPIE = Args.hasArg(options::OPT_pie);
5210f4a2713aSLionel Sambuc bool incStdLib = !Args.hasArg(options::OPT_nostdlib);
5211f4a2713aSLionel Sambuc bool incStartFiles = !Args.hasArg(options::OPT_nostartfiles);
5212f4a2713aSLionel Sambuc bool incDefLibs = !Args.hasArg(options::OPT_nodefaultlibs);
5213f4a2713aSLionel Sambuc bool useShared = buildingLib && !hasStaticArg;
5214f4a2713aSLionel Sambuc
5215f4a2713aSLionel Sambuc //----------------------------------------------------------------------------
5216f4a2713aSLionel Sambuc // Silence warnings for various options
5217f4a2713aSLionel Sambuc //----------------------------------------------------------------------------
5218f4a2713aSLionel Sambuc
5219f4a2713aSLionel Sambuc Args.ClaimAllArgs(options::OPT_g_Group);
5220f4a2713aSLionel Sambuc Args.ClaimAllArgs(options::OPT_emit_llvm);
5221f4a2713aSLionel Sambuc Args.ClaimAllArgs(options::OPT_w); // Other warning options are already
5222f4a2713aSLionel Sambuc // handled somewhere else.
5223f4a2713aSLionel Sambuc Args.ClaimAllArgs(options::OPT_static_libgcc);
5224f4a2713aSLionel Sambuc
5225f4a2713aSLionel Sambuc //----------------------------------------------------------------------------
5226f4a2713aSLionel Sambuc //
5227f4a2713aSLionel Sambuc //----------------------------------------------------------------------------
5228*0a6a1f1dSLionel Sambuc for (const auto &Opt : ToolChain.ExtraOpts)
5229*0a6a1f1dSLionel Sambuc CmdArgs.push_back(Opt.c_str());
5230f4a2713aSLionel Sambuc
5231f4a2713aSLionel Sambuc std::string MarchString = toolchains::Hexagon_TC::GetTargetCPU(Args);
5232f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString("-m" + MarchString));
5233f4a2713aSLionel Sambuc
5234f4a2713aSLionel Sambuc if (buildingLib) {
5235f4a2713aSLionel Sambuc CmdArgs.push_back("-shared");
5236f4a2713aSLionel Sambuc CmdArgs.push_back("-call_shared"); // should be the default, but doing as
5237f4a2713aSLionel Sambuc // hexagon-gcc does
5238f4a2713aSLionel Sambuc }
5239f4a2713aSLionel Sambuc
5240f4a2713aSLionel Sambuc if (hasStaticArg)
5241f4a2713aSLionel Sambuc CmdArgs.push_back("-static");
5242f4a2713aSLionel Sambuc
5243f4a2713aSLionel Sambuc if (buildPIE && !buildingLib)
5244f4a2713aSLionel Sambuc CmdArgs.push_back("-pie");
5245f4a2713aSLionel Sambuc
5246f4a2713aSLionel Sambuc std::string SmallDataThreshold = GetHexagonSmallDataThresholdValue(Args);
5247f4a2713aSLionel Sambuc if (!SmallDataThreshold.empty()) {
5248f4a2713aSLionel Sambuc CmdArgs.push_back(
5249f4a2713aSLionel Sambuc Args.MakeArgString(std::string("-G") + SmallDataThreshold));
5250f4a2713aSLionel Sambuc }
5251f4a2713aSLionel Sambuc
5252f4a2713aSLionel Sambuc //----------------------------------------------------------------------------
5253f4a2713aSLionel Sambuc //
5254f4a2713aSLionel Sambuc //----------------------------------------------------------------------------
5255f4a2713aSLionel Sambuc CmdArgs.push_back("-o");
5256f4a2713aSLionel Sambuc CmdArgs.push_back(Output.getFilename());
5257f4a2713aSLionel Sambuc
5258f4a2713aSLionel Sambuc const std::string MarchSuffix = "/" + MarchString;
5259f4a2713aSLionel Sambuc const std::string G0Suffix = "/G0";
5260f4a2713aSLionel Sambuc const std::string MarchG0Suffix = MarchSuffix + G0Suffix;
5261*0a6a1f1dSLionel Sambuc const std::string RootDir =
5262*0a6a1f1dSLionel Sambuc toolchains::Hexagon_TC::GetGnuDir(D.InstalledDir, Args) + "/";
5263f4a2713aSLionel Sambuc const std::string StartFilesDir = RootDir
5264f4a2713aSLionel Sambuc + "hexagon/lib"
5265f4a2713aSLionel Sambuc + (buildingLib
5266f4a2713aSLionel Sambuc ? MarchG0Suffix : MarchSuffix);
5267f4a2713aSLionel Sambuc
5268f4a2713aSLionel Sambuc //----------------------------------------------------------------------------
5269f4a2713aSLionel Sambuc // moslib
5270f4a2713aSLionel Sambuc //----------------------------------------------------------------------------
5271f4a2713aSLionel Sambuc std::vector<std::string> oslibs;
5272f4a2713aSLionel Sambuc bool hasStandalone= false;
5273f4a2713aSLionel Sambuc
5274f4a2713aSLionel Sambuc for (arg_iterator it = Args.filtered_begin(options::OPT_moslib_EQ),
5275f4a2713aSLionel Sambuc ie = Args.filtered_end(); it != ie; ++it) {
5276f4a2713aSLionel Sambuc (*it)->claim();
5277f4a2713aSLionel Sambuc oslibs.push_back((*it)->getValue());
5278f4a2713aSLionel Sambuc hasStandalone = hasStandalone || (oslibs.back() == "standalone");
5279f4a2713aSLionel Sambuc }
5280f4a2713aSLionel Sambuc if (oslibs.empty()) {
5281f4a2713aSLionel Sambuc oslibs.push_back("standalone");
5282f4a2713aSLionel Sambuc hasStandalone = true;
5283f4a2713aSLionel Sambuc }
5284f4a2713aSLionel Sambuc
5285f4a2713aSLionel Sambuc //----------------------------------------------------------------------------
5286f4a2713aSLionel Sambuc // Start Files
5287f4a2713aSLionel Sambuc //----------------------------------------------------------------------------
5288f4a2713aSLionel Sambuc if (incStdLib && incStartFiles) {
5289f4a2713aSLionel Sambuc
5290f4a2713aSLionel Sambuc if (!buildingLib) {
5291f4a2713aSLionel Sambuc if (hasStandalone) {
5292f4a2713aSLionel Sambuc CmdArgs.push_back(
5293f4a2713aSLionel Sambuc Args.MakeArgString(StartFilesDir + "/crt0_standalone.o"));
5294f4a2713aSLionel Sambuc }
5295f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(StartFilesDir + "/crt0.o"));
5296f4a2713aSLionel Sambuc }
5297f4a2713aSLionel Sambuc std::string initObj = useShared ? "/initS.o" : "/init.o";
5298f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(StartFilesDir + initObj));
5299f4a2713aSLionel Sambuc }
5300f4a2713aSLionel Sambuc
5301f4a2713aSLionel Sambuc //----------------------------------------------------------------------------
5302f4a2713aSLionel Sambuc // Library Search Paths
5303f4a2713aSLionel Sambuc //----------------------------------------------------------------------------
5304f4a2713aSLionel Sambuc const ToolChain::path_list &LibPaths = ToolChain.getFilePaths();
5305*0a6a1f1dSLionel Sambuc for (const auto &LibPath : LibPaths)
5306*0a6a1f1dSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + LibPath));
5307f4a2713aSLionel Sambuc
5308f4a2713aSLionel Sambuc //----------------------------------------------------------------------------
5309f4a2713aSLionel Sambuc //
5310f4a2713aSLionel Sambuc //----------------------------------------------------------------------------
5311f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
5312f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_e);
5313f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_s);
5314f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_t);
5315f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_u_Group);
5316f4a2713aSLionel Sambuc
5317f4a2713aSLionel Sambuc AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
5318f4a2713aSLionel Sambuc
5319f4a2713aSLionel Sambuc //----------------------------------------------------------------------------
5320f4a2713aSLionel Sambuc // Libraries
5321f4a2713aSLionel Sambuc //----------------------------------------------------------------------------
5322f4a2713aSLionel Sambuc if (incStdLib && incDefLibs) {
5323f4a2713aSLionel Sambuc if (D.CCCIsCXX()) {
5324f4a2713aSLionel Sambuc ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
5325f4a2713aSLionel Sambuc CmdArgs.push_back("-lm");
5326f4a2713aSLionel Sambuc }
5327f4a2713aSLionel Sambuc
5328f4a2713aSLionel Sambuc CmdArgs.push_back("--start-group");
5329f4a2713aSLionel Sambuc
5330f4a2713aSLionel Sambuc if (!buildingLib) {
5331f4a2713aSLionel Sambuc for(std::vector<std::string>::iterator i = oslibs.begin(),
5332f4a2713aSLionel Sambuc e = oslibs.end(); i != e; ++i)
5333f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString("-l" + *i));
5334f4a2713aSLionel Sambuc CmdArgs.push_back("-lc");
5335f4a2713aSLionel Sambuc }
5336f4a2713aSLionel Sambuc CmdArgs.push_back("-lgcc");
5337f4a2713aSLionel Sambuc
5338f4a2713aSLionel Sambuc CmdArgs.push_back("--end-group");
5339f4a2713aSLionel Sambuc }
5340f4a2713aSLionel Sambuc
5341f4a2713aSLionel Sambuc //----------------------------------------------------------------------------
5342f4a2713aSLionel Sambuc // End files
5343f4a2713aSLionel Sambuc //----------------------------------------------------------------------------
5344f4a2713aSLionel Sambuc if (incStdLib && incStartFiles) {
5345f4a2713aSLionel Sambuc std::string finiObj = useShared ? "/finiS.o" : "/fini.o";
5346f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(StartFilesDir + finiObj));
5347f4a2713aSLionel Sambuc }
5348f4a2713aSLionel Sambuc
5349f4a2713aSLionel Sambuc std::string Linker = ToolChain.GetProgramPath("hexagon-ld");
5350*0a6a1f1dSLionel Sambuc C.addCommand(llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Linker),
5351*0a6a1f1dSLionel Sambuc CmdArgs));
5352f4a2713aSLionel Sambuc }
5353f4a2713aSLionel Sambuc // Hexagon tools end.
5354f4a2713aSLionel Sambuc
5355*0a6a1f1dSLionel Sambuc /// Get the (LLVM) name of the minimum ARM CPU for the arch we are targeting.
getARMCPUForMArch(const ArgList & Args,const llvm::Triple & Triple)5356*0a6a1f1dSLionel Sambuc const char *arm::getARMCPUForMArch(const ArgList &Args,
5357*0a6a1f1dSLionel Sambuc const llvm::Triple &Triple) {
5358*0a6a1f1dSLionel Sambuc StringRef MArch;
5359*0a6a1f1dSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
5360*0a6a1f1dSLionel Sambuc // Otherwise, if we have -march= choose the base CPU for that arch.
5361*0a6a1f1dSLionel Sambuc MArch = A->getValue();
5362*0a6a1f1dSLionel Sambuc } else {
5363*0a6a1f1dSLionel Sambuc // Otherwise, use the Arch from the triple.
5364*0a6a1f1dSLionel Sambuc MArch = Triple.getArchName();
5365*0a6a1f1dSLionel Sambuc }
5366*0a6a1f1dSLionel Sambuc
5367*0a6a1f1dSLionel Sambuc // Handle -march=native.
5368*0a6a1f1dSLionel Sambuc if (MArch == "native") {
5369*0a6a1f1dSLionel Sambuc std::string CPU = llvm::sys::getHostCPUName();
5370*0a6a1f1dSLionel Sambuc if (CPU != "generic") {
5371*0a6a1f1dSLionel Sambuc // Translate the native cpu into the architecture. The switch below will
5372*0a6a1f1dSLionel Sambuc // then chose the minimum cpu for that arch.
5373*0a6a1f1dSLionel Sambuc MArch = std::string("arm") + arm::getLLVMArchSuffixForARM(CPU);
5374*0a6a1f1dSLionel Sambuc }
5375*0a6a1f1dSLionel Sambuc }
5376*0a6a1f1dSLionel Sambuc
5377*0a6a1f1dSLionel Sambuc return Triple.getARMCPUForArch(MArch);
5378*0a6a1f1dSLionel Sambuc }
5379*0a6a1f1dSLionel Sambuc
5380*0a6a1f1dSLionel Sambuc /// getARMTargetCPU - Get the (LLVM) name of the ARM cpu we are targeting.
getARMTargetCPU(const ArgList & Args,const llvm::Triple & Triple)5381*0a6a1f1dSLionel Sambuc StringRef arm::getARMTargetCPU(const ArgList &Args,
5382*0a6a1f1dSLionel Sambuc const llvm::Triple &Triple) {
5383*0a6a1f1dSLionel Sambuc // FIXME: Warn on inconsistent use of -mcpu and -march.
5384*0a6a1f1dSLionel Sambuc // If we have -mcpu=, use that.
5385*0a6a1f1dSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
5386*0a6a1f1dSLionel Sambuc StringRef MCPU = A->getValue();
5387*0a6a1f1dSLionel Sambuc // Handle -mcpu=native.
5388*0a6a1f1dSLionel Sambuc if (MCPU == "native")
5389*0a6a1f1dSLionel Sambuc return llvm::sys::getHostCPUName();
5390*0a6a1f1dSLionel Sambuc else
5391*0a6a1f1dSLionel Sambuc return MCPU;
5392*0a6a1f1dSLionel Sambuc }
5393*0a6a1f1dSLionel Sambuc
5394*0a6a1f1dSLionel Sambuc return getARMCPUForMArch(Args, Triple);
5395*0a6a1f1dSLionel Sambuc }
5396*0a6a1f1dSLionel Sambuc
5397*0a6a1f1dSLionel Sambuc /// getLLVMArchSuffixForARM - Get the LLVM arch name to use for a particular
5398*0a6a1f1dSLionel Sambuc /// CPU.
5399*0a6a1f1dSLionel Sambuc //
5400*0a6a1f1dSLionel Sambuc // FIXME: This is redundant with -mcpu, why does LLVM use this.
5401*0a6a1f1dSLionel Sambuc // FIXME: tblgen this, or kill it!
getLLVMArchSuffixForARM(StringRef CPU)5402*0a6a1f1dSLionel Sambuc const char *arm::getLLVMArchSuffixForARM(StringRef CPU) {
5403*0a6a1f1dSLionel Sambuc return llvm::StringSwitch<const char *>(CPU)
5404*0a6a1f1dSLionel Sambuc .Case("strongarm", "v4")
5405*0a6a1f1dSLionel Sambuc .Cases("arm7tdmi", "arm7tdmi-s", "arm710t", "v4t")
5406*0a6a1f1dSLionel Sambuc .Cases("arm720t", "arm9", "arm9tdmi", "v4t")
5407*0a6a1f1dSLionel Sambuc .Cases("arm920", "arm920t", "arm922t", "v4t")
5408*0a6a1f1dSLionel Sambuc .Cases("arm940t", "ep9312","v4t")
5409*0a6a1f1dSLionel Sambuc .Cases("arm10tdmi", "arm1020t", "v5")
5410*0a6a1f1dSLionel Sambuc .Cases("arm9e", "arm926ej-s", "arm946e-s", "v5e")
5411*0a6a1f1dSLionel Sambuc .Cases("arm966e-s", "arm968e-s", "arm10e", "v5e")
5412*0a6a1f1dSLionel Sambuc .Cases("arm1020e", "arm1022e", "xscale", "iwmmxt", "v5e")
5413*0a6a1f1dSLionel Sambuc .Cases("arm1136j-s", "arm1136jf-s", "arm1176jz-s", "v6")
5414*0a6a1f1dSLionel Sambuc .Cases("arm1176jzf-s", "mpcorenovfp", "mpcore", "v6")
5415*0a6a1f1dSLionel Sambuc .Cases("arm1156t2-s", "arm1156t2f-s", "v6t2")
5416*0a6a1f1dSLionel Sambuc .Cases("cortex-a5", "cortex-a7", "cortex-a8", "v7")
5417*0a6a1f1dSLionel Sambuc .Cases("cortex-a9", "cortex-a12", "cortex-a15", "cortex-a17", "krait", "v7")
5418*0a6a1f1dSLionel Sambuc .Cases("cortex-r4", "cortex-r5", "v7r")
5419*0a6a1f1dSLionel Sambuc .Case("cortex-m0", "v6m")
5420*0a6a1f1dSLionel Sambuc .Case("cortex-m3", "v7m")
5421*0a6a1f1dSLionel Sambuc .Cases("cortex-m4", "cortex-m7", "v7em")
5422*0a6a1f1dSLionel Sambuc .Case("swift", "v7s")
5423*0a6a1f1dSLionel Sambuc .Case("cyclone", "v8")
5424*0a6a1f1dSLionel Sambuc .Cases("cortex-a53", "cortex-a57", "v8")
5425*0a6a1f1dSLionel Sambuc .Default("");
5426*0a6a1f1dSLionel Sambuc }
5427*0a6a1f1dSLionel Sambuc
appendEBLinkFlags(const ArgList & Args,ArgStringList & CmdArgs,const llvm::Triple & Triple)5428*0a6a1f1dSLionel Sambuc void arm::appendEBLinkFlags(const ArgList &Args, ArgStringList &CmdArgs, const llvm::Triple &Triple) {
5429*0a6a1f1dSLionel Sambuc if (Args.hasArg(options::OPT_r))
5430*0a6a1f1dSLionel Sambuc return;
5431*0a6a1f1dSLionel Sambuc
5432*0a6a1f1dSLionel Sambuc StringRef Suffix = getLLVMArchSuffixForARM(getARMCPUForMArch(Args, Triple));
5433*0a6a1f1dSLionel Sambuc const char *LinkFlag = llvm::StringSwitch<const char *>(Suffix)
5434*0a6a1f1dSLionel Sambuc .Cases("v4", "v4t", "v5", "v5e", nullptr)
5435*0a6a1f1dSLionel Sambuc .Cases("v6", "v6t2", nullptr)
5436*0a6a1f1dSLionel Sambuc .Default("--be8");
5437*0a6a1f1dSLionel Sambuc
5438*0a6a1f1dSLionel Sambuc if (LinkFlag)
5439*0a6a1f1dSLionel Sambuc CmdArgs.push_back(LinkFlag);
5440*0a6a1f1dSLionel Sambuc }
5441*0a6a1f1dSLionel Sambuc
hasMipsAbiArg(const ArgList & Args,const char * Value)5442*0a6a1f1dSLionel Sambuc bool mips::hasMipsAbiArg(const ArgList &Args, const char *Value) {
5443*0a6a1f1dSLionel Sambuc Arg *A = Args.getLastArg(options::OPT_mabi_EQ);
5444*0a6a1f1dSLionel Sambuc return A && (A->getValue() == StringRef(Value));
5445*0a6a1f1dSLionel Sambuc }
5446*0a6a1f1dSLionel Sambuc
isUCLibc(const ArgList & Args)5447*0a6a1f1dSLionel Sambuc bool mips::isUCLibc(const ArgList &Args) {
5448*0a6a1f1dSLionel Sambuc Arg *A = Args.getLastArg(options::OPT_m_libc_Group);
5449*0a6a1f1dSLionel Sambuc return A && A->getOption().matches(options::OPT_muclibc);
5450*0a6a1f1dSLionel Sambuc }
5451*0a6a1f1dSLionel Sambuc
isNaN2008(const ArgList & Args,const llvm::Triple & Triple)5452*0a6a1f1dSLionel Sambuc bool mips::isNaN2008(const ArgList &Args, const llvm::Triple &Triple) {
5453*0a6a1f1dSLionel Sambuc if (Arg *NaNArg = Args.getLastArg(options::OPT_mnan_EQ))
5454*0a6a1f1dSLionel Sambuc return llvm::StringSwitch<bool>(NaNArg->getValue())
5455*0a6a1f1dSLionel Sambuc .Case("2008", true)
5456*0a6a1f1dSLionel Sambuc .Case("legacy", false)
5457*0a6a1f1dSLionel Sambuc .Default(false);
5458*0a6a1f1dSLionel Sambuc
5459*0a6a1f1dSLionel Sambuc // NaN2008 is the default for MIPS32r6/MIPS64r6.
5460*0a6a1f1dSLionel Sambuc return llvm::StringSwitch<bool>(getCPUName(Args, Triple))
5461*0a6a1f1dSLionel Sambuc .Cases("mips32r6", "mips64r6", true)
5462*0a6a1f1dSLionel Sambuc .Default(false);
5463*0a6a1f1dSLionel Sambuc
5464*0a6a1f1dSLionel Sambuc return false;
5465*0a6a1f1dSLionel Sambuc }
5466*0a6a1f1dSLionel Sambuc
isFPXXDefault(const llvm::Triple & Triple,StringRef CPUName,StringRef ABIName)5467*0a6a1f1dSLionel Sambuc bool mips::isFPXXDefault(const llvm::Triple &Triple, StringRef CPUName,
5468*0a6a1f1dSLionel Sambuc StringRef ABIName) {
5469*0a6a1f1dSLionel Sambuc if (Triple.getVendor() != llvm::Triple::ImaginationTechnologies &&
5470*0a6a1f1dSLionel Sambuc Triple.getVendor() != llvm::Triple::MipsTechnologies)
5471*0a6a1f1dSLionel Sambuc return false;
5472*0a6a1f1dSLionel Sambuc
5473*0a6a1f1dSLionel Sambuc if (ABIName != "32")
5474*0a6a1f1dSLionel Sambuc return false;
5475*0a6a1f1dSLionel Sambuc
5476*0a6a1f1dSLionel Sambuc return llvm::StringSwitch<bool>(CPUName)
5477*0a6a1f1dSLionel Sambuc .Cases("mips2", "mips3", "mips4", "mips5", true)
5478*0a6a1f1dSLionel Sambuc .Cases("mips32", "mips32r2", true)
5479*0a6a1f1dSLionel Sambuc .Cases("mips64", "mips64r2", true)
5480*0a6a1f1dSLionel Sambuc .Default(false);
5481*0a6a1f1dSLionel Sambuc }
5482*0a6a1f1dSLionel Sambuc
getArchTypeForMachOArchName(StringRef Str)5483*0a6a1f1dSLionel Sambuc llvm::Triple::ArchType darwin::getArchTypeForMachOArchName(StringRef Str) {
5484f4a2713aSLionel Sambuc // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for
5485f4a2713aSLionel Sambuc // archs which Darwin doesn't use.
5486f4a2713aSLionel Sambuc
5487f4a2713aSLionel Sambuc // The matching this routine does is fairly pointless, since it is neither the
5488f4a2713aSLionel Sambuc // complete architecture list, nor a reasonable subset. The problem is that
5489f4a2713aSLionel Sambuc // historically the driver driver accepts this and also ties its -march=
5490f4a2713aSLionel Sambuc // handling to the architecture name, so we need to be careful before removing
5491f4a2713aSLionel Sambuc // support for it.
5492f4a2713aSLionel Sambuc
5493f4a2713aSLionel Sambuc // This code must be kept in sync with Clang's Darwin specific argument
5494f4a2713aSLionel Sambuc // translation.
5495f4a2713aSLionel Sambuc
5496f4a2713aSLionel Sambuc return llvm::StringSwitch<llvm::Triple::ArchType>(Str)
5497f4a2713aSLionel Sambuc .Cases("ppc", "ppc601", "ppc603", "ppc604", "ppc604e", llvm::Triple::ppc)
5498f4a2713aSLionel Sambuc .Cases("ppc750", "ppc7400", "ppc7450", "ppc970", llvm::Triple::ppc)
5499f4a2713aSLionel Sambuc .Case("ppc64", llvm::Triple::ppc64)
5500f4a2713aSLionel Sambuc .Cases("i386", "i486", "i486SX", "i586", "i686", llvm::Triple::x86)
5501f4a2713aSLionel Sambuc .Cases("pentium", "pentpro", "pentIIm3", "pentIIm5", "pentium4",
5502f4a2713aSLionel Sambuc llvm::Triple::x86)
5503f4a2713aSLionel Sambuc .Cases("x86_64", "x86_64h", llvm::Triple::x86_64)
5504f4a2713aSLionel Sambuc // This is derived from the driver driver.
5505f4a2713aSLionel Sambuc .Cases("arm", "armv4t", "armv5", "armv6", "armv6m", llvm::Triple::arm)
5506*0a6a1f1dSLionel Sambuc .Cases("armv7", "armv7em", "armv7k", "armv7m", llvm::Triple::arm)
5507f4a2713aSLionel Sambuc .Cases("armv7s", "xscale", llvm::Triple::arm)
5508*0a6a1f1dSLionel Sambuc .Case("arm64", llvm::Triple::aarch64)
5509f4a2713aSLionel Sambuc .Case("r600", llvm::Triple::r600)
5510*0a6a1f1dSLionel Sambuc .Case("amdgcn", llvm::Triple::amdgcn)
5511f4a2713aSLionel Sambuc .Case("nvptx", llvm::Triple::nvptx)
5512f4a2713aSLionel Sambuc .Case("nvptx64", llvm::Triple::nvptx64)
5513f4a2713aSLionel Sambuc .Case("amdil", llvm::Triple::amdil)
5514f4a2713aSLionel Sambuc .Case("spir", llvm::Triple::spir)
5515f4a2713aSLionel Sambuc .Default(llvm::Triple::UnknownArch);
5516f4a2713aSLionel Sambuc }
5517f4a2713aSLionel Sambuc
setTripleTypeForMachOArchName(llvm::Triple & T,StringRef Str)5518*0a6a1f1dSLionel Sambuc void darwin::setTripleTypeForMachOArchName(llvm::Triple &T, StringRef Str) {
5519*0a6a1f1dSLionel Sambuc llvm::Triple::ArchType Arch = getArchTypeForMachOArchName(Str);
5520*0a6a1f1dSLionel Sambuc T.setArch(Arch);
5521*0a6a1f1dSLionel Sambuc
5522*0a6a1f1dSLionel Sambuc if (Str == "x86_64h")
5523*0a6a1f1dSLionel Sambuc T.setArchName(Str);
5524*0a6a1f1dSLionel Sambuc else if (Str == "armv6m" || Str == "armv7m" || Str == "armv7em") {
5525*0a6a1f1dSLionel Sambuc T.setOS(llvm::Triple::UnknownOS);
5526*0a6a1f1dSLionel Sambuc T.setObjectFormat(llvm::Triple::MachO);
5527*0a6a1f1dSLionel Sambuc }
5528*0a6a1f1dSLionel Sambuc }
5529*0a6a1f1dSLionel Sambuc
getBaseInputName(const ArgList & Args,const InputInfoList & Inputs)5530f4a2713aSLionel Sambuc const char *Clang::getBaseInputName(const ArgList &Args,
5531f4a2713aSLionel Sambuc const InputInfoList &Inputs) {
5532f4a2713aSLionel Sambuc return Args.MakeArgString(
5533f4a2713aSLionel Sambuc llvm::sys::path::filename(Inputs[0].getBaseInput()));
5534f4a2713aSLionel Sambuc }
5535f4a2713aSLionel Sambuc
getBaseInputStem(const ArgList & Args,const InputInfoList & Inputs)5536f4a2713aSLionel Sambuc const char *Clang::getBaseInputStem(const ArgList &Args,
5537f4a2713aSLionel Sambuc const InputInfoList &Inputs) {
5538f4a2713aSLionel Sambuc const char *Str = getBaseInputName(Args, Inputs);
5539f4a2713aSLionel Sambuc
5540f4a2713aSLionel Sambuc if (const char *End = strrchr(Str, '.'))
5541f4a2713aSLionel Sambuc return Args.MakeArgString(std::string(Str, End));
5542f4a2713aSLionel Sambuc
5543f4a2713aSLionel Sambuc return Str;
5544f4a2713aSLionel Sambuc }
5545f4a2713aSLionel Sambuc
getDependencyFileName(const ArgList & Args,const InputInfoList & Inputs)5546f4a2713aSLionel Sambuc const char *Clang::getDependencyFileName(const ArgList &Args,
5547f4a2713aSLionel Sambuc const InputInfoList &Inputs) {
5548f4a2713aSLionel Sambuc // FIXME: Think about this more.
5549f4a2713aSLionel Sambuc std::string Res;
5550f4a2713aSLionel Sambuc
5551f4a2713aSLionel Sambuc if (Arg *OutputOpt = Args.getLastArg(options::OPT_o)) {
5552f4a2713aSLionel Sambuc std::string Str(OutputOpt->getValue());
5553f4a2713aSLionel Sambuc Res = Str.substr(0, Str.rfind('.'));
5554f4a2713aSLionel Sambuc } else {
5555f4a2713aSLionel Sambuc Res = getBaseInputStem(Args, Inputs);
5556f4a2713aSLionel Sambuc }
5557f4a2713aSLionel Sambuc return Args.MakeArgString(Res + ".d");
5558f4a2713aSLionel Sambuc }
5559f4a2713aSLionel Sambuc
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const5560f4a2713aSLionel Sambuc void darwin::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
5561f4a2713aSLionel Sambuc const InputInfo &Output,
5562f4a2713aSLionel Sambuc const InputInfoList &Inputs,
5563f4a2713aSLionel Sambuc const ArgList &Args,
5564f4a2713aSLionel Sambuc const char *LinkingOutput) const {
5565f4a2713aSLionel Sambuc ArgStringList CmdArgs;
5566f4a2713aSLionel Sambuc
5567f4a2713aSLionel Sambuc assert(Inputs.size() == 1 && "Unexpected number of inputs.");
5568f4a2713aSLionel Sambuc const InputInfo &Input = Inputs[0];
5569f4a2713aSLionel Sambuc
5570f4a2713aSLionel Sambuc // Determine the original source input.
5571f4a2713aSLionel Sambuc const Action *SourceAction = &JA;
5572f4a2713aSLionel Sambuc while (SourceAction->getKind() != Action::InputClass) {
5573f4a2713aSLionel Sambuc assert(!SourceAction->getInputs().empty() && "unexpected root action!");
5574f4a2713aSLionel Sambuc SourceAction = SourceAction->getInputs()[0];
5575f4a2713aSLionel Sambuc }
5576f4a2713aSLionel Sambuc
5577*0a6a1f1dSLionel Sambuc // If -fno_integrated_as is used add -Q to the darwin assember driver to make
5578f4a2713aSLionel Sambuc // sure it runs its system assembler not clang's integrated assembler.
5579*0a6a1f1dSLionel Sambuc // Applicable to darwin11+ and Xcode 4+. darwin<10 lacked integrated-as.
5580*0a6a1f1dSLionel Sambuc // FIXME: at run-time detect assembler capabilities or rely on version
5581*0a6a1f1dSLionel Sambuc // information forwarded by -target-assembler-version (future)
5582*0a6a1f1dSLionel Sambuc if (Args.hasArg(options::OPT_fno_integrated_as)) {
5583*0a6a1f1dSLionel Sambuc const llvm::Triple &T(getToolChain().getTriple());
5584*0a6a1f1dSLionel Sambuc if (!(T.isMacOSX() && T.isMacOSXVersionLT(10, 7)))
5585f4a2713aSLionel Sambuc CmdArgs.push_back("-Q");
5586*0a6a1f1dSLionel Sambuc }
5587f4a2713aSLionel Sambuc
5588f4a2713aSLionel Sambuc // Forward -g, assuming we are dealing with an actual assembly file.
5589f4a2713aSLionel Sambuc if (SourceAction->getType() == types::TY_Asm ||
5590f4a2713aSLionel Sambuc SourceAction->getType() == types::TY_PP_Asm) {
5591f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_gstabs))
5592f4a2713aSLionel Sambuc CmdArgs.push_back("--gstabs");
5593f4a2713aSLionel Sambuc else if (Args.hasArg(options::OPT_g_Group))
5594f4a2713aSLionel Sambuc CmdArgs.push_back("-g");
5595f4a2713aSLionel Sambuc }
5596f4a2713aSLionel Sambuc
5597f4a2713aSLionel Sambuc // Derived from asm spec.
5598*0a6a1f1dSLionel Sambuc AddMachOArch(Args, CmdArgs);
5599f4a2713aSLionel Sambuc
5600f4a2713aSLionel Sambuc // Use -force_cpusubtype_ALL on x86 by default.
5601f4a2713aSLionel Sambuc if (getToolChain().getArch() == llvm::Triple::x86 ||
5602f4a2713aSLionel Sambuc getToolChain().getArch() == llvm::Triple::x86_64 ||
5603f4a2713aSLionel Sambuc Args.hasArg(options::OPT_force__cpusubtype__ALL))
5604f4a2713aSLionel Sambuc CmdArgs.push_back("-force_cpusubtype_ALL");
5605f4a2713aSLionel Sambuc
5606f4a2713aSLionel Sambuc if (getToolChain().getArch() != llvm::Triple::x86_64 &&
5607f4a2713aSLionel Sambuc (((Args.hasArg(options::OPT_mkernel) ||
5608f4a2713aSLionel Sambuc Args.hasArg(options::OPT_fapple_kext)) &&
5609*0a6a1f1dSLionel Sambuc getMachOToolChain().isKernelStatic()) ||
5610f4a2713aSLionel Sambuc Args.hasArg(options::OPT_static)))
5611f4a2713aSLionel Sambuc CmdArgs.push_back("-static");
5612f4a2713aSLionel Sambuc
5613f4a2713aSLionel Sambuc Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
5614f4a2713aSLionel Sambuc options::OPT_Xassembler);
5615f4a2713aSLionel Sambuc
5616f4a2713aSLionel Sambuc assert(Output.isFilename() && "Unexpected lipo output.");
5617f4a2713aSLionel Sambuc CmdArgs.push_back("-o");
5618f4a2713aSLionel Sambuc CmdArgs.push_back(Output.getFilename());
5619f4a2713aSLionel Sambuc
5620f4a2713aSLionel Sambuc assert(Input.isFilename() && "Invalid input.");
5621f4a2713aSLionel Sambuc CmdArgs.push_back(Input.getFilename());
5622f4a2713aSLionel Sambuc
5623f4a2713aSLionel Sambuc // asm_final spec is empty.
5624f4a2713aSLionel Sambuc
5625f4a2713aSLionel Sambuc const char *Exec =
5626f4a2713aSLionel Sambuc Args.MakeArgString(getToolChain().GetProgramPath("as"));
5627*0a6a1f1dSLionel Sambuc C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
5628f4a2713aSLionel Sambuc }
5629f4a2713aSLionel Sambuc
anchor()5630*0a6a1f1dSLionel Sambuc void darwin::MachOTool::anchor() {}
5631f4a2713aSLionel Sambuc
AddMachOArch(const ArgList & Args,ArgStringList & CmdArgs) const5632*0a6a1f1dSLionel Sambuc void darwin::MachOTool::AddMachOArch(const ArgList &Args,
5633f4a2713aSLionel Sambuc ArgStringList &CmdArgs) const {
5634*0a6a1f1dSLionel Sambuc StringRef ArchName = getMachOToolChain().getMachOArchName(Args);
5635f4a2713aSLionel Sambuc
5636f4a2713aSLionel Sambuc // Derived from darwin_arch spec.
5637f4a2713aSLionel Sambuc CmdArgs.push_back("-arch");
5638f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(ArchName));
5639f4a2713aSLionel Sambuc
5640f4a2713aSLionel Sambuc // FIXME: Is this needed anymore?
5641f4a2713aSLionel Sambuc if (ArchName == "arm")
5642f4a2713aSLionel Sambuc CmdArgs.push_back("-force_cpusubtype_ALL");
5643f4a2713aSLionel Sambuc }
5644f4a2713aSLionel Sambuc
NeedsTempPath(const InputInfoList & Inputs) const5645f4a2713aSLionel Sambuc bool darwin::Link::NeedsTempPath(const InputInfoList &Inputs) const {
5646f4a2713aSLionel Sambuc // We only need to generate a temp path for LTO if we aren't compiling object
5647f4a2713aSLionel Sambuc // files. When compiling source files, we run 'dsymutil' after linking. We
5648f4a2713aSLionel Sambuc // don't run 'dsymutil' when compiling object files.
5649*0a6a1f1dSLionel Sambuc for (const auto &Input : Inputs)
5650*0a6a1f1dSLionel Sambuc if (Input.getType() != types::TY_Object)
5651f4a2713aSLionel Sambuc return true;
5652f4a2713aSLionel Sambuc
5653f4a2713aSLionel Sambuc return false;
5654f4a2713aSLionel Sambuc }
5655f4a2713aSLionel Sambuc
AddLinkArgs(Compilation & C,const ArgList & Args,ArgStringList & CmdArgs,const InputInfoList & Inputs) const5656f4a2713aSLionel Sambuc void darwin::Link::AddLinkArgs(Compilation &C,
5657f4a2713aSLionel Sambuc const ArgList &Args,
5658f4a2713aSLionel Sambuc ArgStringList &CmdArgs,
5659f4a2713aSLionel Sambuc const InputInfoList &Inputs) const {
5660f4a2713aSLionel Sambuc const Driver &D = getToolChain().getDriver();
5661*0a6a1f1dSLionel Sambuc const toolchains::MachO &MachOTC = getMachOToolChain();
5662f4a2713aSLionel Sambuc
5663f4a2713aSLionel Sambuc unsigned Version[3] = { 0, 0, 0 };
5664f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ)) {
5665f4a2713aSLionel Sambuc bool HadExtra;
5666f4a2713aSLionel Sambuc if (!Driver::GetReleaseVersion(A->getValue(), Version[0],
5667f4a2713aSLionel Sambuc Version[1], Version[2], HadExtra) ||
5668f4a2713aSLionel Sambuc HadExtra)
5669f4a2713aSLionel Sambuc D.Diag(diag::err_drv_invalid_version_number)
5670f4a2713aSLionel Sambuc << A->getAsString(Args);
5671f4a2713aSLionel Sambuc }
5672f4a2713aSLionel Sambuc
5673*0a6a1f1dSLionel Sambuc // Newer linkers support -demangle. Pass it if supported and not disabled by
5674f4a2713aSLionel Sambuc // the user.
5675*0a6a1f1dSLionel Sambuc if (Version[0] >= 100 && !Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
5676f4a2713aSLionel Sambuc CmdArgs.push_back("-demangle");
5677f4a2713aSLionel Sambuc
5678f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_rdynamic) && Version[0] >= 137)
5679f4a2713aSLionel Sambuc CmdArgs.push_back("-export_dynamic");
5680f4a2713aSLionel Sambuc
5681f4a2713aSLionel Sambuc // If we are using LTO, then automatically create a temporary file path for
5682f4a2713aSLionel Sambuc // the linker to use, so that it's lifetime will extend past a possible
5683f4a2713aSLionel Sambuc // dsymutil step.
5684f4a2713aSLionel Sambuc if (Version[0] >= 116 && D.IsUsingLTO(Args) && NeedsTempPath(Inputs)) {
5685f4a2713aSLionel Sambuc const char *TmpPath = C.getArgs().MakeArgString(
5686f4a2713aSLionel Sambuc D.GetTemporaryPath("cc", types::getTypeTempSuffix(types::TY_Object)));
5687f4a2713aSLionel Sambuc C.addTempFile(TmpPath);
5688f4a2713aSLionel Sambuc CmdArgs.push_back("-object_path_lto");
5689f4a2713aSLionel Sambuc CmdArgs.push_back(TmpPath);
5690f4a2713aSLionel Sambuc }
5691f4a2713aSLionel Sambuc
5692f4a2713aSLionel Sambuc // Derived from the "link" spec.
5693f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_static);
5694f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_static))
5695f4a2713aSLionel Sambuc CmdArgs.push_back("-dynamic");
5696f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_fgnu_runtime)) {
5697f4a2713aSLionel Sambuc // FIXME: gcc replaces -lobjc in forward args with -lobjc-gnu
5698f4a2713aSLionel Sambuc // here. How do we wish to handle such things?
5699f4a2713aSLionel Sambuc }
5700f4a2713aSLionel Sambuc
5701f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_dynamiclib)) {
5702*0a6a1f1dSLionel Sambuc AddMachOArch(Args, CmdArgs);
5703f4a2713aSLionel Sambuc // FIXME: Why do this only on this path?
5704f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_force__cpusubtype__ALL);
5705f4a2713aSLionel Sambuc
5706f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_bundle);
5707f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_bundle__loader);
5708f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_client__name);
5709f4a2713aSLionel Sambuc
5710f4a2713aSLionel Sambuc Arg *A;
5711f4a2713aSLionel Sambuc if ((A = Args.getLastArg(options::OPT_compatibility__version)) ||
5712f4a2713aSLionel Sambuc (A = Args.getLastArg(options::OPT_current__version)) ||
5713f4a2713aSLionel Sambuc (A = Args.getLastArg(options::OPT_install__name)))
5714f4a2713aSLionel Sambuc D.Diag(diag::err_drv_argument_only_allowed_with)
5715f4a2713aSLionel Sambuc << A->getAsString(Args) << "-dynamiclib";
5716f4a2713aSLionel Sambuc
5717f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_force__flat__namespace);
5718f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_keep__private__externs);
5719f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_private__bundle);
5720f4a2713aSLionel Sambuc } else {
5721f4a2713aSLionel Sambuc CmdArgs.push_back("-dylib");
5722f4a2713aSLionel Sambuc
5723f4a2713aSLionel Sambuc Arg *A;
5724f4a2713aSLionel Sambuc if ((A = Args.getLastArg(options::OPT_bundle)) ||
5725f4a2713aSLionel Sambuc (A = Args.getLastArg(options::OPT_bundle__loader)) ||
5726f4a2713aSLionel Sambuc (A = Args.getLastArg(options::OPT_client__name)) ||
5727f4a2713aSLionel Sambuc (A = Args.getLastArg(options::OPT_force__flat__namespace)) ||
5728f4a2713aSLionel Sambuc (A = Args.getLastArg(options::OPT_keep__private__externs)) ||
5729f4a2713aSLionel Sambuc (A = Args.getLastArg(options::OPT_private__bundle)))
5730f4a2713aSLionel Sambuc D.Diag(diag::err_drv_argument_not_allowed_with)
5731f4a2713aSLionel Sambuc << A->getAsString(Args) << "-dynamiclib";
5732f4a2713aSLionel Sambuc
5733f4a2713aSLionel Sambuc Args.AddAllArgsTranslated(CmdArgs, options::OPT_compatibility__version,
5734f4a2713aSLionel Sambuc "-dylib_compatibility_version");
5735f4a2713aSLionel Sambuc Args.AddAllArgsTranslated(CmdArgs, options::OPT_current__version,
5736f4a2713aSLionel Sambuc "-dylib_current_version");
5737f4a2713aSLionel Sambuc
5738*0a6a1f1dSLionel Sambuc AddMachOArch(Args, CmdArgs);
5739f4a2713aSLionel Sambuc
5740f4a2713aSLionel Sambuc Args.AddAllArgsTranslated(CmdArgs, options::OPT_install__name,
5741f4a2713aSLionel Sambuc "-dylib_install_name");
5742f4a2713aSLionel Sambuc }
5743f4a2713aSLionel Sambuc
5744f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_all__load);
5745f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_allowable__client);
5746f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_bind__at__load);
5747*0a6a1f1dSLionel Sambuc if (MachOTC.isTargetIOSBased())
5748f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_arch__errors__fatal);
5749f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_dead__strip);
5750f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_no__dead__strip__inits__and__terms);
5751f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_dylib__file);
5752f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_dynamic);
5753f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_exported__symbols__list);
5754f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_flat__namespace);
5755f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_force__load);
5756f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_headerpad__max__install__names);
5757f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_image__base);
5758f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_init);
5759f4a2713aSLionel Sambuc
5760f4a2713aSLionel Sambuc // Add the deployment target.
5761*0a6a1f1dSLionel Sambuc MachOTC.addMinVersionArgs(Args, CmdArgs);
5762f4a2713aSLionel Sambuc
5763f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_nomultidefs);
5764f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_multi__module);
5765f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_single__module);
5766f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined);
5767f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined__unused);
5768f4a2713aSLionel Sambuc
5769f4a2713aSLionel Sambuc if (const Arg *A = Args.getLastArg(options::OPT_fpie, options::OPT_fPIE,
5770f4a2713aSLionel Sambuc options::OPT_fno_pie,
5771f4a2713aSLionel Sambuc options::OPT_fno_PIE)) {
5772f4a2713aSLionel Sambuc if (A->getOption().matches(options::OPT_fpie) ||
5773f4a2713aSLionel Sambuc A->getOption().matches(options::OPT_fPIE))
5774f4a2713aSLionel Sambuc CmdArgs.push_back("-pie");
5775f4a2713aSLionel Sambuc else
5776f4a2713aSLionel Sambuc CmdArgs.push_back("-no_pie");
5777f4a2713aSLionel Sambuc }
5778f4a2713aSLionel Sambuc
5779f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_prebind);
5780f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_noprebind);
5781f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_nofixprebinding);
5782f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_prebind__all__twolevel__modules);
5783f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_read__only__relocs);
5784f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_sectcreate);
5785f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_sectorder);
5786f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_seg1addr);
5787f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_segprot);
5788f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_segaddr);
5789f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_segs__read__only__addr);
5790f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_segs__read__write__addr);
5791f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_seg__addr__table);
5792f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_seg__addr__table__filename);
5793f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_sub__library);
5794f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_sub__umbrella);
5795f4a2713aSLionel Sambuc
5796f4a2713aSLionel Sambuc // Give --sysroot= preference, over the Apple specific behavior to also use
5797f4a2713aSLionel Sambuc // --isysroot as the syslibroot.
5798f4a2713aSLionel Sambuc StringRef sysroot = C.getSysRoot();
5799f4a2713aSLionel Sambuc if (sysroot != "") {
5800f4a2713aSLionel Sambuc CmdArgs.push_back("-syslibroot");
5801f4a2713aSLionel Sambuc CmdArgs.push_back(C.getArgs().MakeArgString(sysroot));
5802f4a2713aSLionel Sambuc } else if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
5803f4a2713aSLionel Sambuc CmdArgs.push_back("-syslibroot");
5804f4a2713aSLionel Sambuc CmdArgs.push_back(A->getValue());
5805f4a2713aSLionel Sambuc }
5806f4a2713aSLionel Sambuc
5807f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace);
5808f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace__hints);
5809f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_umbrella);
5810f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_undefined);
5811f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_unexported__symbols__list);
5812f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_weak__reference__mismatches);
5813f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_X_Flag);
5814f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_y);
5815f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_w);
5816f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_pagezero__size);
5817f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_segs__read__);
5818f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_seglinkedit);
5819f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_noseglinkedit);
5820f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_sectalign);
5821f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_sectobjectsymbols);
5822f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_segcreate);
5823f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_whyload);
5824f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_whatsloaded);
5825f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_dylinker__install__name);
5826f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_dylinker);
5827f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_Mach);
5828f4a2713aSLionel Sambuc }
5829f4a2713aSLionel Sambuc
5830*0a6a1f1dSLionel Sambuc enum LibOpenMP {
5831*0a6a1f1dSLionel Sambuc LibUnknown,
5832*0a6a1f1dSLionel Sambuc LibGOMP,
5833*0a6a1f1dSLionel Sambuc LibIOMP5
5834*0a6a1f1dSLionel Sambuc };
5835*0a6a1f1dSLionel Sambuc
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const5836f4a2713aSLionel Sambuc void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA,
5837f4a2713aSLionel Sambuc const InputInfo &Output,
5838f4a2713aSLionel Sambuc const InputInfoList &Inputs,
5839f4a2713aSLionel Sambuc const ArgList &Args,
5840f4a2713aSLionel Sambuc const char *LinkingOutput) const {
5841f4a2713aSLionel Sambuc assert(Output.getType() == types::TY_Image && "Invalid linker output type.");
5842f4a2713aSLionel Sambuc
5843*0a6a1f1dSLionel Sambuc // If the number of arguments surpasses the system limits, we will encode the
5844*0a6a1f1dSLionel Sambuc // input files in a separate file, shortening the command line. To this end,
5845*0a6a1f1dSLionel Sambuc // build a list of input file names that can be passed via a file with the
5846*0a6a1f1dSLionel Sambuc // -filelist linker option.
5847*0a6a1f1dSLionel Sambuc llvm::opt::ArgStringList InputFileList;
5848*0a6a1f1dSLionel Sambuc
5849f4a2713aSLionel Sambuc // The logic here is derived from gcc's behavior; most of which
5850f4a2713aSLionel Sambuc // comes from specs (starting with link_command). Consult gcc for
5851f4a2713aSLionel Sambuc // more information.
5852f4a2713aSLionel Sambuc ArgStringList CmdArgs;
5853f4a2713aSLionel Sambuc
5854f4a2713aSLionel Sambuc /// Hack(tm) to ignore linking errors when we are doing ARC migration.
5855f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_ccc_arcmt_check,
5856f4a2713aSLionel Sambuc options::OPT_ccc_arcmt_migrate)) {
5857*0a6a1f1dSLionel Sambuc for (const auto &Arg : Args)
5858*0a6a1f1dSLionel Sambuc Arg->claim();
5859f4a2713aSLionel Sambuc const char *Exec =
5860f4a2713aSLionel Sambuc Args.MakeArgString(getToolChain().GetProgramPath("touch"));
5861f4a2713aSLionel Sambuc CmdArgs.push_back(Output.getFilename());
5862*0a6a1f1dSLionel Sambuc C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
5863f4a2713aSLionel Sambuc return;
5864f4a2713aSLionel Sambuc }
5865f4a2713aSLionel Sambuc
5866f4a2713aSLionel Sambuc // I'm not sure why this particular decomposition exists in gcc, but
5867f4a2713aSLionel Sambuc // we follow suite for ease of comparison.
5868f4a2713aSLionel Sambuc AddLinkArgs(C, Args, CmdArgs, Inputs);
5869f4a2713aSLionel Sambuc
5870f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_d_Flag);
5871f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_s);
5872f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_t);
5873f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag);
5874f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_u_Group);
5875f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_e);
5876f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_r);
5877f4a2713aSLionel Sambuc
5878f4a2713aSLionel Sambuc // Forward -ObjC when either -ObjC or -ObjC++ is used, to force loading
5879f4a2713aSLionel Sambuc // members of static archive libraries which implement Objective-C classes or
5880f4a2713aSLionel Sambuc // categories.
5881f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_ObjC) || Args.hasArg(options::OPT_ObjCXX))
5882f4a2713aSLionel Sambuc CmdArgs.push_back("-ObjC");
5883f4a2713aSLionel Sambuc
5884f4a2713aSLionel Sambuc CmdArgs.push_back("-o");
5885f4a2713aSLionel Sambuc CmdArgs.push_back(Output.getFilename());
5886f4a2713aSLionel Sambuc
5887f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_nostdlib) &&
5888*0a6a1f1dSLionel Sambuc !Args.hasArg(options::OPT_nostartfiles))
5889*0a6a1f1dSLionel Sambuc getMachOToolChain().addStartObjectFileArgs(Args, CmdArgs);
5890f4a2713aSLionel Sambuc
5891f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_L);
5892f4a2713aSLionel Sambuc
5893*0a6a1f1dSLionel Sambuc LibOpenMP UsedOpenMPLib = LibUnknown;
5894*0a6a1f1dSLionel Sambuc if (Args.hasArg(options::OPT_fopenmp)) {
5895*0a6a1f1dSLionel Sambuc UsedOpenMPLib = LibGOMP;
5896*0a6a1f1dSLionel Sambuc } else if (const Arg *A = Args.getLastArg(options::OPT_fopenmp_EQ)) {
5897*0a6a1f1dSLionel Sambuc UsedOpenMPLib = llvm::StringSwitch<LibOpenMP>(A->getValue())
5898*0a6a1f1dSLionel Sambuc .Case("libgomp", LibGOMP)
5899*0a6a1f1dSLionel Sambuc .Case("libiomp5", LibIOMP5)
5900*0a6a1f1dSLionel Sambuc .Default(LibUnknown);
5901*0a6a1f1dSLionel Sambuc if (UsedOpenMPLib == LibUnknown)
5902*0a6a1f1dSLionel Sambuc getToolChain().getDriver().Diag(diag::err_drv_unsupported_option_argument)
5903*0a6a1f1dSLionel Sambuc << A->getOption().getName() << A->getValue();
5904*0a6a1f1dSLionel Sambuc }
5905*0a6a1f1dSLionel Sambuc switch (UsedOpenMPLib) {
5906*0a6a1f1dSLionel Sambuc case LibGOMP:
5907f4a2713aSLionel Sambuc CmdArgs.push_back("-lgomp");
5908*0a6a1f1dSLionel Sambuc break;
5909*0a6a1f1dSLionel Sambuc case LibIOMP5:
5910*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-liomp5");
5911*0a6a1f1dSLionel Sambuc break;
5912*0a6a1f1dSLionel Sambuc case LibUnknown:
5913*0a6a1f1dSLionel Sambuc break;
5914*0a6a1f1dSLionel Sambuc }
5915f4a2713aSLionel Sambuc
5916f4a2713aSLionel Sambuc AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
5917*0a6a1f1dSLionel Sambuc // Build the input file for -filelist (list of linker input files) in case we
5918*0a6a1f1dSLionel Sambuc // need it later
5919*0a6a1f1dSLionel Sambuc for (const auto &II : Inputs) {
5920*0a6a1f1dSLionel Sambuc if (!II.isFilename()) {
5921*0a6a1f1dSLionel Sambuc // This is a linker input argument.
5922*0a6a1f1dSLionel Sambuc // We cannot mix input arguments and file names in a -filelist input, thus
5923*0a6a1f1dSLionel Sambuc // we prematurely stop our list (remaining files shall be passed as
5924*0a6a1f1dSLionel Sambuc // arguments).
5925*0a6a1f1dSLionel Sambuc if (InputFileList.size() > 0)
5926*0a6a1f1dSLionel Sambuc break;
5927*0a6a1f1dSLionel Sambuc
5928*0a6a1f1dSLionel Sambuc continue;
5929*0a6a1f1dSLionel Sambuc }
5930*0a6a1f1dSLionel Sambuc
5931*0a6a1f1dSLionel Sambuc InputFileList.push_back(II.getFilename());
5932*0a6a1f1dSLionel Sambuc }
5933f4a2713aSLionel Sambuc
5934f4a2713aSLionel Sambuc if (isObjCRuntimeLinked(Args) &&
5935f4a2713aSLionel Sambuc !Args.hasArg(options::OPT_nostdlib) &&
5936f4a2713aSLionel Sambuc !Args.hasArg(options::OPT_nodefaultlibs)) {
5937f4a2713aSLionel Sambuc // We use arclite library for both ARC and subscripting support.
5938*0a6a1f1dSLionel Sambuc getMachOToolChain().AddLinkARCArgs(Args, CmdArgs);
5939*0a6a1f1dSLionel Sambuc
5940f4a2713aSLionel Sambuc CmdArgs.push_back("-framework");
5941f4a2713aSLionel Sambuc CmdArgs.push_back("Foundation");
5942f4a2713aSLionel Sambuc // Link libobj.
5943f4a2713aSLionel Sambuc CmdArgs.push_back("-lobjc");
5944f4a2713aSLionel Sambuc }
5945f4a2713aSLionel Sambuc
5946f4a2713aSLionel Sambuc if (LinkingOutput) {
5947f4a2713aSLionel Sambuc CmdArgs.push_back("-arch_multiple");
5948f4a2713aSLionel Sambuc CmdArgs.push_back("-final_output");
5949f4a2713aSLionel Sambuc CmdArgs.push_back(LinkingOutput);
5950f4a2713aSLionel Sambuc }
5951f4a2713aSLionel Sambuc
5952f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_fnested_functions))
5953f4a2713aSLionel Sambuc CmdArgs.push_back("-allow_stack_execute");
5954f4a2713aSLionel Sambuc
5955f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_nostdlib) &&
5956f4a2713aSLionel Sambuc !Args.hasArg(options::OPT_nodefaultlibs)) {
5957f4a2713aSLionel Sambuc if (getToolChain().getDriver().CCCIsCXX())
5958f4a2713aSLionel Sambuc getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
5959f4a2713aSLionel Sambuc
5960f4a2713aSLionel Sambuc // link_ssp spec is empty.
5961f4a2713aSLionel Sambuc
5962f4a2713aSLionel Sambuc // Let the tool chain choose which runtime library to link.
5963*0a6a1f1dSLionel Sambuc getMachOToolChain().AddLinkRuntimeLibArgs(Args, CmdArgs);
5964f4a2713aSLionel Sambuc }
5965f4a2713aSLionel Sambuc
5966f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_nostdlib) &&
5967f4a2713aSLionel Sambuc !Args.hasArg(options::OPT_nostartfiles)) {
5968f4a2713aSLionel Sambuc // endfile_spec is empty.
5969f4a2713aSLionel Sambuc }
5970f4a2713aSLionel Sambuc
5971f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
5972f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_F);
5973f4a2713aSLionel Sambuc
5974f4a2713aSLionel Sambuc const char *Exec =
5975*0a6a1f1dSLionel Sambuc Args.MakeArgString(getToolChain().GetLinkerPath());
5976*0a6a1f1dSLionel Sambuc std::unique_ptr<Command> Cmd =
5977*0a6a1f1dSLionel Sambuc llvm::make_unique<Command>(JA, *this, Exec, CmdArgs);
5978*0a6a1f1dSLionel Sambuc Cmd->setInputFileList(std::move(InputFileList));
5979*0a6a1f1dSLionel Sambuc C.addCommand(std::move(Cmd));
5980f4a2713aSLionel Sambuc }
5981f4a2713aSLionel Sambuc
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const5982f4a2713aSLionel Sambuc void darwin::Lipo::ConstructJob(Compilation &C, const JobAction &JA,
5983f4a2713aSLionel Sambuc const InputInfo &Output,
5984f4a2713aSLionel Sambuc const InputInfoList &Inputs,
5985f4a2713aSLionel Sambuc const ArgList &Args,
5986f4a2713aSLionel Sambuc const char *LinkingOutput) const {
5987f4a2713aSLionel Sambuc ArgStringList CmdArgs;
5988f4a2713aSLionel Sambuc
5989f4a2713aSLionel Sambuc CmdArgs.push_back("-create");
5990f4a2713aSLionel Sambuc assert(Output.isFilename() && "Unexpected lipo output.");
5991f4a2713aSLionel Sambuc
5992f4a2713aSLionel Sambuc CmdArgs.push_back("-output");
5993f4a2713aSLionel Sambuc CmdArgs.push_back(Output.getFilename());
5994f4a2713aSLionel Sambuc
5995*0a6a1f1dSLionel Sambuc for (const auto &II : Inputs) {
5996f4a2713aSLionel Sambuc assert(II.isFilename() && "Unexpected lipo input.");
5997f4a2713aSLionel Sambuc CmdArgs.push_back(II.getFilename());
5998f4a2713aSLionel Sambuc }
5999*0a6a1f1dSLionel Sambuc
6000*0a6a1f1dSLionel Sambuc const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("lipo"));
6001*0a6a1f1dSLionel Sambuc C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
6002f4a2713aSLionel Sambuc }
6003f4a2713aSLionel Sambuc
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const6004f4a2713aSLionel Sambuc void darwin::Dsymutil::ConstructJob(Compilation &C, const JobAction &JA,
6005f4a2713aSLionel Sambuc const InputInfo &Output,
6006f4a2713aSLionel Sambuc const InputInfoList &Inputs,
6007f4a2713aSLionel Sambuc const ArgList &Args,
6008f4a2713aSLionel Sambuc const char *LinkingOutput) const {
6009f4a2713aSLionel Sambuc ArgStringList CmdArgs;
6010f4a2713aSLionel Sambuc
6011f4a2713aSLionel Sambuc CmdArgs.push_back("-o");
6012f4a2713aSLionel Sambuc CmdArgs.push_back(Output.getFilename());
6013f4a2713aSLionel Sambuc
6014f4a2713aSLionel Sambuc assert(Inputs.size() == 1 && "Unable to handle multiple inputs.");
6015f4a2713aSLionel Sambuc const InputInfo &Input = Inputs[0];
6016f4a2713aSLionel Sambuc assert(Input.isFilename() && "Unexpected dsymutil input.");
6017f4a2713aSLionel Sambuc CmdArgs.push_back(Input.getFilename());
6018f4a2713aSLionel Sambuc
6019f4a2713aSLionel Sambuc const char *Exec =
6020f4a2713aSLionel Sambuc Args.MakeArgString(getToolChain().GetProgramPath("dsymutil"));
6021*0a6a1f1dSLionel Sambuc C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
6022f4a2713aSLionel Sambuc }
6023f4a2713aSLionel Sambuc
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const6024f4a2713aSLionel Sambuc void darwin::VerifyDebug::ConstructJob(Compilation &C, const JobAction &JA,
6025f4a2713aSLionel Sambuc const InputInfo &Output,
6026f4a2713aSLionel Sambuc const InputInfoList &Inputs,
6027f4a2713aSLionel Sambuc const ArgList &Args,
6028f4a2713aSLionel Sambuc const char *LinkingOutput) const {
6029f4a2713aSLionel Sambuc ArgStringList CmdArgs;
6030f4a2713aSLionel Sambuc CmdArgs.push_back("--verify");
6031f4a2713aSLionel Sambuc CmdArgs.push_back("--debug-info");
6032f4a2713aSLionel Sambuc CmdArgs.push_back("--eh-frame");
6033f4a2713aSLionel Sambuc CmdArgs.push_back("--quiet");
6034f4a2713aSLionel Sambuc
6035f4a2713aSLionel Sambuc assert(Inputs.size() == 1 && "Unable to handle multiple inputs.");
6036f4a2713aSLionel Sambuc const InputInfo &Input = Inputs[0];
6037f4a2713aSLionel Sambuc assert(Input.isFilename() && "Unexpected verify input");
6038f4a2713aSLionel Sambuc
6039f4a2713aSLionel Sambuc // Grabbing the output of the earlier dsymutil run.
6040f4a2713aSLionel Sambuc CmdArgs.push_back(Input.getFilename());
6041f4a2713aSLionel Sambuc
6042f4a2713aSLionel Sambuc const char *Exec =
6043f4a2713aSLionel Sambuc Args.MakeArgString(getToolChain().GetProgramPath("dwarfdump"));
6044*0a6a1f1dSLionel Sambuc C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
6045f4a2713aSLionel Sambuc }
6046f4a2713aSLionel Sambuc
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const6047f4a2713aSLionel Sambuc void solaris::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
6048f4a2713aSLionel Sambuc const InputInfo &Output,
6049f4a2713aSLionel Sambuc const InputInfoList &Inputs,
6050f4a2713aSLionel Sambuc const ArgList &Args,
6051f4a2713aSLionel Sambuc const char *LinkingOutput) const {
6052*0a6a1f1dSLionel Sambuc claimNoWarnArgs(Args);
6053f4a2713aSLionel Sambuc ArgStringList CmdArgs;
6054f4a2713aSLionel Sambuc
6055f4a2713aSLionel Sambuc Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
6056f4a2713aSLionel Sambuc options::OPT_Xassembler);
6057f4a2713aSLionel Sambuc
6058f4a2713aSLionel Sambuc CmdArgs.push_back("-o");
6059f4a2713aSLionel Sambuc CmdArgs.push_back(Output.getFilename());
6060f4a2713aSLionel Sambuc
6061*0a6a1f1dSLionel Sambuc for (const auto &II : Inputs)
6062f4a2713aSLionel Sambuc CmdArgs.push_back(II.getFilename());
6063f4a2713aSLionel Sambuc
6064*0a6a1f1dSLionel Sambuc const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
6065*0a6a1f1dSLionel Sambuc C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
6066f4a2713aSLionel Sambuc }
6067f4a2713aSLionel Sambuc
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const6068f4a2713aSLionel Sambuc void solaris::Link::ConstructJob(Compilation &C, const JobAction &JA,
6069f4a2713aSLionel Sambuc const InputInfo &Output,
6070f4a2713aSLionel Sambuc const InputInfoList &Inputs,
6071f4a2713aSLionel Sambuc const ArgList &Args,
6072f4a2713aSLionel Sambuc const char *LinkingOutput) const {
6073f4a2713aSLionel Sambuc // FIXME: Find a real GCC, don't hard-code versions here
6074f4a2713aSLionel Sambuc std::string GCCLibPath = "/usr/gcc/4.5/lib/gcc/";
6075f4a2713aSLionel Sambuc const llvm::Triple &T = getToolChain().getTriple();
6076f4a2713aSLionel Sambuc std::string LibPath = "/usr/lib/";
6077f4a2713aSLionel Sambuc llvm::Triple::ArchType Arch = T.getArch();
6078f4a2713aSLionel Sambuc switch (Arch) {
6079f4a2713aSLionel Sambuc case llvm::Triple::x86:
6080f4a2713aSLionel Sambuc GCCLibPath +=
6081f4a2713aSLionel Sambuc ("i386-" + T.getVendorName() + "-" + T.getOSName()).str() + "/4.5.2/";
6082f4a2713aSLionel Sambuc break;
6083f4a2713aSLionel Sambuc case llvm::Triple::x86_64:
6084f4a2713aSLionel Sambuc GCCLibPath += ("i386-" + T.getVendorName() + "-" + T.getOSName()).str();
6085f4a2713aSLionel Sambuc GCCLibPath += "/4.5.2/amd64/";
6086f4a2713aSLionel Sambuc LibPath += "amd64/";
6087f4a2713aSLionel Sambuc break;
6088f4a2713aSLionel Sambuc default:
6089f4a2713aSLionel Sambuc llvm_unreachable("Unsupported architecture");
6090f4a2713aSLionel Sambuc }
6091f4a2713aSLionel Sambuc
6092f4a2713aSLionel Sambuc ArgStringList CmdArgs;
6093f4a2713aSLionel Sambuc
6094f4a2713aSLionel Sambuc // Demangle C++ names in errors
6095f4a2713aSLionel Sambuc CmdArgs.push_back("-C");
6096f4a2713aSLionel Sambuc
6097f4a2713aSLionel Sambuc if ((!Args.hasArg(options::OPT_nostdlib)) &&
6098f4a2713aSLionel Sambuc (!Args.hasArg(options::OPT_shared))) {
6099f4a2713aSLionel Sambuc CmdArgs.push_back("-e");
6100f4a2713aSLionel Sambuc CmdArgs.push_back("_start");
6101f4a2713aSLionel Sambuc }
6102f4a2713aSLionel Sambuc
6103f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_static)) {
6104f4a2713aSLionel Sambuc CmdArgs.push_back("-Bstatic");
6105f4a2713aSLionel Sambuc CmdArgs.push_back("-dn");
6106f4a2713aSLionel Sambuc } else {
6107f4a2713aSLionel Sambuc CmdArgs.push_back("-Bdynamic");
6108f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_shared)) {
6109f4a2713aSLionel Sambuc CmdArgs.push_back("-shared");
6110f4a2713aSLionel Sambuc } else {
6111f4a2713aSLionel Sambuc CmdArgs.push_back("--dynamic-linker");
6112f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(LibPath + "ld.so.1"));
6113f4a2713aSLionel Sambuc }
6114f4a2713aSLionel Sambuc }
6115f4a2713aSLionel Sambuc
6116f4a2713aSLionel Sambuc if (Output.isFilename()) {
6117f4a2713aSLionel Sambuc CmdArgs.push_back("-o");
6118f4a2713aSLionel Sambuc CmdArgs.push_back(Output.getFilename());
6119f4a2713aSLionel Sambuc } else {
6120f4a2713aSLionel Sambuc assert(Output.isNothing() && "Invalid output.");
6121f4a2713aSLionel Sambuc }
6122f4a2713aSLionel Sambuc
6123f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_nostdlib) &&
6124f4a2713aSLionel Sambuc !Args.hasArg(options::OPT_nostartfiles)) {
6125f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_shared)) {
6126f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(LibPath + "crt1.o"));
6127f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(LibPath + "crti.o"));
6128f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(LibPath + "values-Xa.o"));
6129f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(GCCLibPath + "crtbegin.o"));
6130f4a2713aSLionel Sambuc } else {
6131f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(LibPath + "crti.o"));
6132f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(LibPath + "values-Xa.o"));
6133f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(GCCLibPath + "crtbegin.o"));
6134f4a2713aSLionel Sambuc }
6135f4a2713aSLionel Sambuc if (getToolChain().getDriver().CCCIsCXX())
6136f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(LibPath + "cxa_finalize.o"));
6137f4a2713aSLionel Sambuc }
6138f4a2713aSLionel Sambuc
6139f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString("-L" + GCCLibPath));
6140f4a2713aSLionel Sambuc
6141f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_L);
6142f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
6143f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_e);
6144f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_r);
6145f4a2713aSLionel Sambuc
6146f4a2713aSLionel Sambuc AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
6147f4a2713aSLionel Sambuc
6148f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_nostdlib) &&
6149f4a2713aSLionel Sambuc !Args.hasArg(options::OPT_nodefaultlibs)) {
6150f4a2713aSLionel Sambuc if (getToolChain().getDriver().CCCIsCXX())
6151f4a2713aSLionel Sambuc getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
6152f4a2713aSLionel Sambuc CmdArgs.push_back("-lgcc_s");
6153f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_shared)) {
6154f4a2713aSLionel Sambuc CmdArgs.push_back("-lgcc");
6155f4a2713aSLionel Sambuc CmdArgs.push_back("-lc");
6156f4a2713aSLionel Sambuc CmdArgs.push_back("-lm");
6157f4a2713aSLionel Sambuc }
6158f4a2713aSLionel Sambuc }
6159f4a2713aSLionel Sambuc
6160f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_nostdlib) &&
6161f4a2713aSLionel Sambuc !Args.hasArg(options::OPT_nostartfiles)) {
6162f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(GCCLibPath + "crtend.o"));
6163f4a2713aSLionel Sambuc }
6164f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(LibPath + "crtn.o"));
6165f4a2713aSLionel Sambuc
6166*0a6a1f1dSLionel Sambuc addProfileRT(getToolChain(), Args, CmdArgs);
6167f4a2713aSLionel Sambuc
6168f4a2713aSLionel Sambuc const char *Exec =
6169*0a6a1f1dSLionel Sambuc Args.MakeArgString(getToolChain().GetLinkerPath());
6170*0a6a1f1dSLionel Sambuc C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
6171f4a2713aSLionel Sambuc }
6172f4a2713aSLionel Sambuc
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const6173f4a2713aSLionel Sambuc void openbsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
6174f4a2713aSLionel Sambuc const InputInfo &Output,
6175f4a2713aSLionel Sambuc const InputInfoList &Inputs,
6176f4a2713aSLionel Sambuc const ArgList &Args,
6177f4a2713aSLionel Sambuc const char *LinkingOutput) const {
6178*0a6a1f1dSLionel Sambuc claimNoWarnArgs(Args);
6179f4a2713aSLionel Sambuc ArgStringList CmdArgs;
6180*0a6a1f1dSLionel Sambuc bool NeedsKPIC = false;
6181*0a6a1f1dSLionel Sambuc
6182*0a6a1f1dSLionel Sambuc switch (getToolChain().getArch()) {
6183*0a6a1f1dSLionel Sambuc case llvm::Triple::x86:
6184*0a6a1f1dSLionel Sambuc // When building 32-bit code on OpenBSD/amd64, we have to explicitly
6185*0a6a1f1dSLionel Sambuc // instruct as in the base system to assemble 32-bit code.
6186*0a6a1f1dSLionel Sambuc CmdArgs.push_back("--32");
6187*0a6a1f1dSLionel Sambuc break;
6188*0a6a1f1dSLionel Sambuc
6189*0a6a1f1dSLionel Sambuc case llvm::Triple::ppc:
6190*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-mppc");
6191*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-many");
6192*0a6a1f1dSLionel Sambuc break;
6193*0a6a1f1dSLionel Sambuc
6194*0a6a1f1dSLionel Sambuc case llvm::Triple::sparc:
6195*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-32");
6196*0a6a1f1dSLionel Sambuc NeedsKPIC = true;
6197*0a6a1f1dSLionel Sambuc break;
6198*0a6a1f1dSLionel Sambuc
6199*0a6a1f1dSLionel Sambuc case llvm::Triple::sparcv9:
6200*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-64");
6201*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-Av9a");
6202*0a6a1f1dSLionel Sambuc NeedsKPIC = true;
6203*0a6a1f1dSLionel Sambuc break;
6204*0a6a1f1dSLionel Sambuc
6205*0a6a1f1dSLionel Sambuc case llvm::Triple::mips64:
6206*0a6a1f1dSLionel Sambuc case llvm::Triple::mips64el: {
6207*0a6a1f1dSLionel Sambuc StringRef CPUName;
6208*0a6a1f1dSLionel Sambuc StringRef ABIName;
6209*0a6a1f1dSLionel Sambuc mips::getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName);
6210*0a6a1f1dSLionel Sambuc
6211*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-mabi");
6212*0a6a1f1dSLionel Sambuc CmdArgs.push_back(getGnuCompatibleMipsABIName(ABIName).data());
6213*0a6a1f1dSLionel Sambuc
6214*0a6a1f1dSLionel Sambuc if (getToolChain().getArch() == llvm::Triple::mips64)
6215*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-EB");
6216*0a6a1f1dSLionel Sambuc else
6217*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-EL");
6218*0a6a1f1dSLionel Sambuc
6219*0a6a1f1dSLionel Sambuc NeedsKPIC = true;
6220*0a6a1f1dSLionel Sambuc break;
6221*0a6a1f1dSLionel Sambuc }
6222*0a6a1f1dSLionel Sambuc
6223*0a6a1f1dSLionel Sambuc default:
6224*0a6a1f1dSLionel Sambuc break;
6225*0a6a1f1dSLionel Sambuc }
6226*0a6a1f1dSLionel Sambuc
6227*0a6a1f1dSLionel Sambuc if (NeedsKPIC)
6228*0a6a1f1dSLionel Sambuc addAssemblerKPIC(Args, CmdArgs);
6229f4a2713aSLionel Sambuc
6230f4a2713aSLionel Sambuc Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
6231f4a2713aSLionel Sambuc options::OPT_Xassembler);
6232f4a2713aSLionel Sambuc
6233f4a2713aSLionel Sambuc CmdArgs.push_back("-o");
6234f4a2713aSLionel Sambuc CmdArgs.push_back(Output.getFilename());
6235f4a2713aSLionel Sambuc
6236*0a6a1f1dSLionel Sambuc for (const auto &II : Inputs)
6237f4a2713aSLionel Sambuc CmdArgs.push_back(II.getFilename());
6238f4a2713aSLionel Sambuc
6239f4a2713aSLionel Sambuc const char *Exec =
6240f4a2713aSLionel Sambuc Args.MakeArgString(getToolChain().GetProgramPath("as"));
6241*0a6a1f1dSLionel Sambuc C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
6242f4a2713aSLionel Sambuc }
6243f4a2713aSLionel Sambuc
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const6244f4a2713aSLionel Sambuc void openbsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
6245f4a2713aSLionel Sambuc const InputInfo &Output,
6246f4a2713aSLionel Sambuc const InputInfoList &Inputs,
6247f4a2713aSLionel Sambuc const ArgList &Args,
6248f4a2713aSLionel Sambuc const char *LinkingOutput) const {
6249f4a2713aSLionel Sambuc const Driver &D = getToolChain().getDriver();
6250f4a2713aSLionel Sambuc ArgStringList CmdArgs;
6251f4a2713aSLionel Sambuc
6252f4a2713aSLionel Sambuc // Silence warning for "clang -g foo.o -o foo"
6253f4a2713aSLionel Sambuc Args.ClaimAllArgs(options::OPT_g_Group);
6254f4a2713aSLionel Sambuc // and "clang -emit-llvm foo.o -o foo"
6255f4a2713aSLionel Sambuc Args.ClaimAllArgs(options::OPT_emit_llvm);
6256f4a2713aSLionel Sambuc // and for "clang -w foo.o -o foo". Other warning options are already
6257f4a2713aSLionel Sambuc // handled somewhere else.
6258f4a2713aSLionel Sambuc Args.ClaimAllArgs(options::OPT_w);
6259f4a2713aSLionel Sambuc
6260*0a6a1f1dSLionel Sambuc if (getToolChain().getArch() == llvm::Triple::mips64)
6261*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-EB");
6262*0a6a1f1dSLionel Sambuc else if (getToolChain().getArch() == llvm::Triple::mips64el)
6263*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-EL");
6264*0a6a1f1dSLionel Sambuc
6265f4a2713aSLionel Sambuc if ((!Args.hasArg(options::OPT_nostdlib)) &&
6266f4a2713aSLionel Sambuc (!Args.hasArg(options::OPT_shared))) {
6267f4a2713aSLionel Sambuc CmdArgs.push_back("-e");
6268f4a2713aSLionel Sambuc CmdArgs.push_back("__start");
6269f4a2713aSLionel Sambuc }
6270f4a2713aSLionel Sambuc
6271f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_static)) {
6272f4a2713aSLionel Sambuc CmdArgs.push_back("-Bstatic");
6273f4a2713aSLionel Sambuc } else {
6274f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_rdynamic))
6275f4a2713aSLionel Sambuc CmdArgs.push_back("-export-dynamic");
6276f4a2713aSLionel Sambuc CmdArgs.push_back("--eh-frame-hdr");
6277f4a2713aSLionel Sambuc CmdArgs.push_back("-Bdynamic");
6278f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_shared)) {
6279f4a2713aSLionel Sambuc CmdArgs.push_back("-shared");
6280f4a2713aSLionel Sambuc } else {
6281f4a2713aSLionel Sambuc CmdArgs.push_back("-dynamic-linker");
6282f4a2713aSLionel Sambuc CmdArgs.push_back("/usr/libexec/ld.so");
6283f4a2713aSLionel Sambuc }
6284f4a2713aSLionel Sambuc }
6285f4a2713aSLionel Sambuc
6286f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_nopie))
6287f4a2713aSLionel Sambuc CmdArgs.push_back("-nopie");
6288f4a2713aSLionel Sambuc
6289f4a2713aSLionel Sambuc if (Output.isFilename()) {
6290f4a2713aSLionel Sambuc CmdArgs.push_back("-o");
6291f4a2713aSLionel Sambuc CmdArgs.push_back(Output.getFilename());
6292f4a2713aSLionel Sambuc } else {
6293f4a2713aSLionel Sambuc assert(Output.isNothing() && "Invalid output.");
6294f4a2713aSLionel Sambuc }
6295f4a2713aSLionel Sambuc
6296f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_nostdlib) &&
6297f4a2713aSLionel Sambuc !Args.hasArg(options::OPT_nostartfiles)) {
6298f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_shared)) {
6299f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_pg))
6300f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(
6301f4a2713aSLionel Sambuc getToolChain().GetFilePath("gcrt0.o")));
6302f4a2713aSLionel Sambuc else
6303f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(
6304f4a2713aSLionel Sambuc getToolChain().GetFilePath("crt0.o")));
6305f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(
6306f4a2713aSLionel Sambuc getToolChain().GetFilePath("crtbegin.o")));
6307f4a2713aSLionel Sambuc } else {
6308f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(
6309f4a2713aSLionel Sambuc getToolChain().GetFilePath("crtbeginS.o")));
6310f4a2713aSLionel Sambuc }
6311f4a2713aSLionel Sambuc }
6312f4a2713aSLionel Sambuc
6313f4a2713aSLionel Sambuc std::string Triple = getToolChain().getTripleString();
6314f4a2713aSLionel Sambuc if (Triple.substr(0, 6) == "x86_64")
6315f4a2713aSLionel Sambuc Triple.replace(0, 6, "amd64");
6316f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc-lib/" + Triple +
6317f4a2713aSLionel Sambuc "/4.2.1"));
6318f4a2713aSLionel Sambuc
6319f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_L);
6320f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
6321f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_e);
6322f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_s);
6323f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_t);
6324f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag);
6325f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_r);
6326f4a2713aSLionel Sambuc
6327f4a2713aSLionel Sambuc AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
6328f4a2713aSLionel Sambuc
6329f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_nostdlib) &&
6330f4a2713aSLionel Sambuc !Args.hasArg(options::OPT_nodefaultlibs)) {
6331f4a2713aSLionel Sambuc if (D.CCCIsCXX()) {
6332f4a2713aSLionel Sambuc getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
6333f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_pg))
6334f4a2713aSLionel Sambuc CmdArgs.push_back("-lm_p");
6335f4a2713aSLionel Sambuc else
6336f4a2713aSLionel Sambuc CmdArgs.push_back("-lm");
6337f4a2713aSLionel Sambuc }
6338f4a2713aSLionel Sambuc
6339f4a2713aSLionel Sambuc // FIXME: For some reason GCC passes -lgcc before adding
6340f4a2713aSLionel Sambuc // the default system libraries. Just mimic this for now.
6341f4a2713aSLionel Sambuc CmdArgs.push_back("-lgcc");
6342f4a2713aSLionel Sambuc
6343f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_pthread)) {
6344f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_shared) &&
6345f4a2713aSLionel Sambuc Args.hasArg(options::OPT_pg))
6346f4a2713aSLionel Sambuc CmdArgs.push_back("-lpthread_p");
6347f4a2713aSLionel Sambuc else
6348f4a2713aSLionel Sambuc CmdArgs.push_back("-lpthread");
6349f4a2713aSLionel Sambuc }
6350f4a2713aSLionel Sambuc
6351f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_shared)) {
6352f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_pg))
6353f4a2713aSLionel Sambuc CmdArgs.push_back("-lc_p");
6354f4a2713aSLionel Sambuc else
6355f4a2713aSLionel Sambuc CmdArgs.push_back("-lc");
6356f4a2713aSLionel Sambuc }
6357f4a2713aSLionel Sambuc
6358f4a2713aSLionel Sambuc CmdArgs.push_back("-lgcc");
6359f4a2713aSLionel Sambuc }
6360f4a2713aSLionel Sambuc
6361f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_nostdlib) &&
6362f4a2713aSLionel Sambuc !Args.hasArg(options::OPT_nostartfiles)) {
6363f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_shared))
6364f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(
6365f4a2713aSLionel Sambuc getToolChain().GetFilePath("crtend.o")));
6366f4a2713aSLionel Sambuc else
6367f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(
6368f4a2713aSLionel Sambuc getToolChain().GetFilePath("crtendS.o")));
6369f4a2713aSLionel Sambuc }
6370f4a2713aSLionel Sambuc
6371f4a2713aSLionel Sambuc const char *Exec =
6372*0a6a1f1dSLionel Sambuc Args.MakeArgString(getToolChain().GetLinkerPath());
6373*0a6a1f1dSLionel Sambuc C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
6374f4a2713aSLionel Sambuc }
6375f4a2713aSLionel Sambuc
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const6376f4a2713aSLionel Sambuc void bitrig::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
6377f4a2713aSLionel Sambuc const InputInfo &Output,
6378f4a2713aSLionel Sambuc const InputInfoList &Inputs,
6379f4a2713aSLionel Sambuc const ArgList &Args,
6380f4a2713aSLionel Sambuc const char *LinkingOutput) const {
6381*0a6a1f1dSLionel Sambuc claimNoWarnArgs(Args);
6382f4a2713aSLionel Sambuc ArgStringList CmdArgs;
6383f4a2713aSLionel Sambuc
6384f4a2713aSLionel Sambuc Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
6385f4a2713aSLionel Sambuc options::OPT_Xassembler);
6386f4a2713aSLionel Sambuc
6387f4a2713aSLionel Sambuc CmdArgs.push_back("-o");
6388f4a2713aSLionel Sambuc CmdArgs.push_back(Output.getFilename());
6389f4a2713aSLionel Sambuc
6390*0a6a1f1dSLionel Sambuc for (const auto &II : Inputs)
6391f4a2713aSLionel Sambuc CmdArgs.push_back(II.getFilename());
6392f4a2713aSLionel Sambuc
6393*0a6a1f1dSLionel Sambuc const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
6394*0a6a1f1dSLionel Sambuc C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
6395f4a2713aSLionel Sambuc }
6396f4a2713aSLionel Sambuc
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const6397f4a2713aSLionel Sambuc void bitrig::Link::ConstructJob(Compilation &C, const JobAction &JA,
6398f4a2713aSLionel Sambuc const InputInfo &Output,
6399f4a2713aSLionel Sambuc const InputInfoList &Inputs,
6400f4a2713aSLionel Sambuc const ArgList &Args,
6401f4a2713aSLionel Sambuc const char *LinkingOutput) const {
6402f4a2713aSLionel Sambuc const Driver &D = getToolChain().getDriver();
6403f4a2713aSLionel Sambuc ArgStringList CmdArgs;
6404f4a2713aSLionel Sambuc
6405f4a2713aSLionel Sambuc if ((!Args.hasArg(options::OPT_nostdlib)) &&
6406f4a2713aSLionel Sambuc (!Args.hasArg(options::OPT_shared))) {
6407f4a2713aSLionel Sambuc CmdArgs.push_back("-e");
6408f4a2713aSLionel Sambuc CmdArgs.push_back("__start");
6409f4a2713aSLionel Sambuc }
6410f4a2713aSLionel Sambuc
6411f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_static)) {
6412f4a2713aSLionel Sambuc CmdArgs.push_back("-Bstatic");
6413f4a2713aSLionel Sambuc } else {
6414f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_rdynamic))
6415f4a2713aSLionel Sambuc CmdArgs.push_back("-export-dynamic");
6416f4a2713aSLionel Sambuc CmdArgs.push_back("--eh-frame-hdr");
6417f4a2713aSLionel Sambuc CmdArgs.push_back("-Bdynamic");
6418f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_shared)) {
6419f4a2713aSLionel Sambuc CmdArgs.push_back("-shared");
6420f4a2713aSLionel Sambuc } else {
6421f4a2713aSLionel Sambuc CmdArgs.push_back("-dynamic-linker");
6422f4a2713aSLionel Sambuc CmdArgs.push_back("/usr/libexec/ld.so");
6423f4a2713aSLionel Sambuc }
6424f4a2713aSLionel Sambuc }
6425f4a2713aSLionel Sambuc
6426f4a2713aSLionel Sambuc if (Output.isFilename()) {
6427f4a2713aSLionel Sambuc CmdArgs.push_back("-o");
6428f4a2713aSLionel Sambuc CmdArgs.push_back(Output.getFilename());
6429f4a2713aSLionel Sambuc } else {
6430f4a2713aSLionel Sambuc assert(Output.isNothing() && "Invalid output.");
6431f4a2713aSLionel Sambuc }
6432f4a2713aSLionel Sambuc
6433f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_nostdlib) &&
6434f4a2713aSLionel Sambuc !Args.hasArg(options::OPT_nostartfiles)) {
6435f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_shared)) {
6436f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_pg))
6437f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(
6438f4a2713aSLionel Sambuc getToolChain().GetFilePath("gcrt0.o")));
6439f4a2713aSLionel Sambuc else
6440f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(
6441f4a2713aSLionel Sambuc getToolChain().GetFilePath("crt0.o")));
6442f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(
6443f4a2713aSLionel Sambuc getToolChain().GetFilePath("crtbegin.o")));
6444f4a2713aSLionel Sambuc } else {
6445f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(
6446f4a2713aSLionel Sambuc getToolChain().GetFilePath("crtbeginS.o")));
6447f4a2713aSLionel Sambuc }
6448f4a2713aSLionel Sambuc }
6449f4a2713aSLionel Sambuc
6450f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_L);
6451f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
6452f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_e);
6453f4a2713aSLionel Sambuc
6454f4a2713aSLionel Sambuc AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
6455f4a2713aSLionel Sambuc
6456f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_nostdlib) &&
6457f4a2713aSLionel Sambuc !Args.hasArg(options::OPT_nodefaultlibs)) {
6458f4a2713aSLionel Sambuc if (D.CCCIsCXX()) {
6459f4a2713aSLionel Sambuc getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
6460f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_pg))
6461f4a2713aSLionel Sambuc CmdArgs.push_back("-lm_p");
6462f4a2713aSLionel Sambuc else
6463f4a2713aSLionel Sambuc CmdArgs.push_back("-lm");
6464f4a2713aSLionel Sambuc }
6465f4a2713aSLionel Sambuc
6466f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_pthread)) {
6467f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_shared) &&
6468f4a2713aSLionel Sambuc Args.hasArg(options::OPT_pg))
6469f4a2713aSLionel Sambuc CmdArgs.push_back("-lpthread_p");
6470f4a2713aSLionel Sambuc else
6471f4a2713aSLionel Sambuc CmdArgs.push_back("-lpthread");
6472f4a2713aSLionel Sambuc }
6473f4a2713aSLionel Sambuc
6474f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_shared)) {
6475f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_pg))
6476f4a2713aSLionel Sambuc CmdArgs.push_back("-lc_p");
6477f4a2713aSLionel Sambuc else
6478f4a2713aSLionel Sambuc CmdArgs.push_back("-lc");
6479f4a2713aSLionel Sambuc }
6480f4a2713aSLionel Sambuc
6481f4a2713aSLionel Sambuc StringRef MyArch;
6482f4a2713aSLionel Sambuc switch (getToolChain().getTriple().getArch()) {
6483f4a2713aSLionel Sambuc case llvm::Triple::arm:
6484f4a2713aSLionel Sambuc MyArch = "arm";
6485f4a2713aSLionel Sambuc break;
6486f4a2713aSLionel Sambuc case llvm::Triple::x86:
6487f4a2713aSLionel Sambuc MyArch = "i386";
6488f4a2713aSLionel Sambuc break;
6489f4a2713aSLionel Sambuc case llvm::Triple::x86_64:
6490f4a2713aSLionel Sambuc MyArch = "amd64";
6491f4a2713aSLionel Sambuc break;
6492f4a2713aSLionel Sambuc default:
6493f4a2713aSLionel Sambuc llvm_unreachable("Unsupported architecture");
6494f4a2713aSLionel Sambuc }
6495f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString("-lclang_rt." + MyArch));
6496f4a2713aSLionel Sambuc }
6497f4a2713aSLionel Sambuc
6498f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_nostdlib) &&
6499f4a2713aSLionel Sambuc !Args.hasArg(options::OPT_nostartfiles)) {
6500f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_shared))
6501f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(
6502f4a2713aSLionel Sambuc getToolChain().GetFilePath("crtend.o")));
6503f4a2713aSLionel Sambuc else
6504f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(
6505f4a2713aSLionel Sambuc getToolChain().GetFilePath("crtendS.o")));
6506f4a2713aSLionel Sambuc }
6507f4a2713aSLionel Sambuc
6508f4a2713aSLionel Sambuc const char *Exec =
6509*0a6a1f1dSLionel Sambuc Args.MakeArgString(getToolChain().GetLinkerPath());
6510*0a6a1f1dSLionel Sambuc C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
6511f4a2713aSLionel Sambuc }
6512f4a2713aSLionel Sambuc
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const6513f4a2713aSLionel Sambuc void freebsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
6514f4a2713aSLionel Sambuc const InputInfo &Output,
6515f4a2713aSLionel Sambuc const InputInfoList &Inputs,
6516f4a2713aSLionel Sambuc const ArgList &Args,
6517f4a2713aSLionel Sambuc const char *LinkingOutput) const {
6518*0a6a1f1dSLionel Sambuc claimNoWarnArgs(Args);
6519f4a2713aSLionel Sambuc ArgStringList CmdArgs;
6520f4a2713aSLionel Sambuc
6521f4a2713aSLionel Sambuc // When building 32-bit code on FreeBSD/amd64, we have to explicitly
6522f4a2713aSLionel Sambuc // instruct as in the base system to assemble 32-bit code.
6523f4a2713aSLionel Sambuc if (getToolChain().getArch() == llvm::Triple::x86)
6524f4a2713aSLionel Sambuc CmdArgs.push_back("--32");
6525f4a2713aSLionel Sambuc else if (getToolChain().getArch() == llvm::Triple::ppc)
6526f4a2713aSLionel Sambuc CmdArgs.push_back("-a32");
6527f4a2713aSLionel Sambuc else if (getToolChain().getArch() == llvm::Triple::mips ||
6528f4a2713aSLionel Sambuc getToolChain().getArch() == llvm::Triple::mipsel ||
6529f4a2713aSLionel Sambuc getToolChain().getArch() == llvm::Triple::mips64 ||
6530f4a2713aSLionel Sambuc getToolChain().getArch() == llvm::Triple::mips64el) {
6531f4a2713aSLionel Sambuc StringRef CPUName;
6532f4a2713aSLionel Sambuc StringRef ABIName;
6533*0a6a1f1dSLionel Sambuc mips::getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName);
6534f4a2713aSLionel Sambuc
6535f4a2713aSLionel Sambuc CmdArgs.push_back("-march");
6536f4a2713aSLionel Sambuc CmdArgs.push_back(CPUName.data());
6537f4a2713aSLionel Sambuc
6538f4a2713aSLionel Sambuc CmdArgs.push_back("-mabi");
6539f4a2713aSLionel Sambuc CmdArgs.push_back(getGnuCompatibleMipsABIName(ABIName).data());
6540f4a2713aSLionel Sambuc
6541f4a2713aSLionel Sambuc if (getToolChain().getArch() == llvm::Triple::mips ||
6542f4a2713aSLionel Sambuc getToolChain().getArch() == llvm::Triple::mips64)
6543f4a2713aSLionel Sambuc CmdArgs.push_back("-EB");
6544f4a2713aSLionel Sambuc else
6545f4a2713aSLionel Sambuc CmdArgs.push_back("-EL");
6546f4a2713aSLionel Sambuc
6547*0a6a1f1dSLionel Sambuc addAssemblerKPIC(Args, CmdArgs);
6548f4a2713aSLionel Sambuc } else if (getToolChain().getArch() == llvm::Triple::arm ||
6549*0a6a1f1dSLionel Sambuc getToolChain().getArch() == llvm::Triple::armeb ||
6550*0a6a1f1dSLionel Sambuc getToolChain().getArch() == llvm::Triple::thumb ||
6551*0a6a1f1dSLionel Sambuc getToolChain().getArch() == llvm::Triple::thumbeb) {
6552*0a6a1f1dSLionel Sambuc const Driver &D = getToolChain().getDriver();
6553*0a6a1f1dSLionel Sambuc const llvm::Triple &Triple = getToolChain().getTriple();
6554*0a6a1f1dSLionel Sambuc StringRef FloatABI = arm::getARMFloatABI(D, Args, Triple);
6555*0a6a1f1dSLionel Sambuc
6556*0a6a1f1dSLionel Sambuc if (FloatABI == "hard") {
6557*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-mfpu=vfp");
6558*0a6a1f1dSLionel Sambuc } else {
6559f4a2713aSLionel Sambuc CmdArgs.push_back("-mfpu=softvfp");
6560*0a6a1f1dSLionel Sambuc }
6561*0a6a1f1dSLionel Sambuc
6562f4a2713aSLionel Sambuc switch(getToolChain().getTriple().getEnvironment()) {
6563*0a6a1f1dSLionel Sambuc case llvm::Triple::GNUEABIHF:
6564f4a2713aSLionel Sambuc case llvm::Triple::GNUEABI:
6565f4a2713aSLionel Sambuc case llvm::Triple::EABI:
6566f4a2713aSLionel Sambuc CmdArgs.push_back("-meabi=5");
6567f4a2713aSLionel Sambuc break;
6568f4a2713aSLionel Sambuc
6569f4a2713aSLionel Sambuc default:
6570f4a2713aSLionel Sambuc CmdArgs.push_back("-matpcs");
6571f4a2713aSLionel Sambuc }
6572*0a6a1f1dSLionel Sambuc } else if (getToolChain().getArch() == llvm::Triple::sparc ||
6573*0a6a1f1dSLionel Sambuc getToolChain().getArch() == llvm::Triple::sparcv9) {
6574*0a6a1f1dSLionel Sambuc if (getToolChain().getArch() == llvm::Triple::sparc)
6575*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-Av8plusa");
6576*0a6a1f1dSLionel Sambuc else
6577*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-Av9a");
6578*0a6a1f1dSLionel Sambuc
6579*0a6a1f1dSLionel Sambuc addAssemblerKPIC(Args, CmdArgs);
6580f4a2713aSLionel Sambuc }
6581f4a2713aSLionel Sambuc
6582f4a2713aSLionel Sambuc Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
6583f4a2713aSLionel Sambuc options::OPT_Xassembler);
6584f4a2713aSLionel Sambuc
6585f4a2713aSLionel Sambuc CmdArgs.push_back("-o");
6586f4a2713aSLionel Sambuc CmdArgs.push_back(Output.getFilename());
6587f4a2713aSLionel Sambuc
6588*0a6a1f1dSLionel Sambuc for (const auto &II : Inputs)
6589f4a2713aSLionel Sambuc CmdArgs.push_back(II.getFilename());
6590f4a2713aSLionel Sambuc
6591*0a6a1f1dSLionel Sambuc const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
6592*0a6a1f1dSLionel Sambuc C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
6593f4a2713aSLionel Sambuc }
6594f4a2713aSLionel Sambuc
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const6595f4a2713aSLionel Sambuc void freebsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
6596f4a2713aSLionel Sambuc const InputInfo &Output,
6597f4a2713aSLionel Sambuc const InputInfoList &Inputs,
6598f4a2713aSLionel Sambuc const ArgList &Args,
6599f4a2713aSLionel Sambuc const char *LinkingOutput) const {
6600f4a2713aSLionel Sambuc const toolchains::FreeBSD& ToolChain =
6601f4a2713aSLionel Sambuc static_cast<const toolchains::FreeBSD&>(getToolChain());
6602f4a2713aSLionel Sambuc const Driver &D = ToolChain.getDriver();
6603*0a6a1f1dSLionel Sambuc const bool IsPIE =
6604*0a6a1f1dSLionel Sambuc !Args.hasArg(options::OPT_shared) &&
6605*0a6a1f1dSLionel Sambuc (Args.hasArg(options::OPT_pie) || ToolChain.isPIEDefault());
6606f4a2713aSLionel Sambuc ArgStringList CmdArgs;
6607f4a2713aSLionel Sambuc
6608f4a2713aSLionel Sambuc // Silence warning for "clang -g foo.o -o foo"
6609f4a2713aSLionel Sambuc Args.ClaimAllArgs(options::OPT_g_Group);
6610f4a2713aSLionel Sambuc // and "clang -emit-llvm foo.o -o foo"
6611f4a2713aSLionel Sambuc Args.ClaimAllArgs(options::OPT_emit_llvm);
6612f4a2713aSLionel Sambuc // and for "clang -w foo.o -o foo". Other warning options are already
6613f4a2713aSLionel Sambuc // handled somewhere else.
6614f4a2713aSLionel Sambuc Args.ClaimAllArgs(options::OPT_w);
6615f4a2713aSLionel Sambuc
6616f4a2713aSLionel Sambuc if (!D.SysRoot.empty())
6617f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
6618f4a2713aSLionel Sambuc
6619*0a6a1f1dSLionel Sambuc if (IsPIE)
6620f4a2713aSLionel Sambuc CmdArgs.push_back("-pie");
6621f4a2713aSLionel Sambuc
6622f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_static)) {
6623f4a2713aSLionel Sambuc CmdArgs.push_back("-Bstatic");
6624f4a2713aSLionel Sambuc } else {
6625f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_rdynamic))
6626f4a2713aSLionel Sambuc CmdArgs.push_back("-export-dynamic");
6627f4a2713aSLionel Sambuc CmdArgs.push_back("--eh-frame-hdr");
6628f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_shared)) {
6629f4a2713aSLionel Sambuc CmdArgs.push_back("-Bshareable");
6630f4a2713aSLionel Sambuc } else {
6631f4a2713aSLionel Sambuc CmdArgs.push_back("-dynamic-linker");
6632f4a2713aSLionel Sambuc CmdArgs.push_back("/libexec/ld-elf.so.1");
6633f4a2713aSLionel Sambuc }
6634f4a2713aSLionel Sambuc if (ToolChain.getTriple().getOSMajorVersion() >= 9) {
6635f4a2713aSLionel Sambuc llvm::Triple::ArchType Arch = ToolChain.getArch();
6636f4a2713aSLionel Sambuc if (Arch == llvm::Triple::arm || Arch == llvm::Triple::sparc ||
6637f4a2713aSLionel Sambuc Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64) {
6638f4a2713aSLionel Sambuc CmdArgs.push_back("--hash-style=both");
6639f4a2713aSLionel Sambuc }
6640f4a2713aSLionel Sambuc }
6641f4a2713aSLionel Sambuc CmdArgs.push_back("--enable-new-dtags");
6642f4a2713aSLionel Sambuc }
6643f4a2713aSLionel Sambuc
6644f4a2713aSLionel Sambuc // When building 32-bit code on FreeBSD/amd64, we have to explicitly
6645f4a2713aSLionel Sambuc // instruct ld in the base system to link 32-bit code.
6646f4a2713aSLionel Sambuc if (ToolChain.getArch() == llvm::Triple::x86) {
6647f4a2713aSLionel Sambuc CmdArgs.push_back("-m");
6648f4a2713aSLionel Sambuc CmdArgs.push_back("elf_i386_fbsd");
6649f4a2713aSLionel Sambuc }
6650f4a2713aSLionel Sambuc
6651f4a2713aSLionel Sambuc if (ToolChain.getArch() == llvm::Triple::ppc) {
6652f4a2713aSLionel Sambuc CmdArgs.push_back("-m");
6653f4a2713aSLionel Sambuc CmdArgs.push_back("elf32ppc_fbsd");
6654f4a2713aSLionel Sambuc }
6655f4a2713aSLionel Sambuc
6656f4a2713aSLionel Sambuc if (Output.isFilename()) {
6657f4a2713aSLionel Sambuc CmdArgs.push_back("-o");
6658f4a2713aSLionel Sambuc CmdArgs.push_back(Output.getFilename());
6659f4a2713aSLionel Sambuc } else {
6660f4a2713aSLionel Sambuc assert(Output.isNothing() && "Invalid output.");
6661f4a2713aSLionel Sambuc }
6662f4a2713aSLionel Sambuc
6663f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_nostdlib) &&
6664f4a2713aSLionel Sambuc !Args.hasArg(options::OPT_nostartfiles)) {
6665*0a6a1f1dSLionel Sambuc const char *crt1 = nullptr;
6666f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_shared)) {
6667f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_pg))
6668f4a2713aSLionel Sambuc crt1 = "gcrt1.o";
6669*0a6a1f1dSLionel Sambuc else if (IsPIE)
6670f4a2713aSLionel Sambuc crt1 = "Scrt1.o";
6671f4a2713aSLionel Sambuc else
6672f4a2713aSLionel Sambuc crt1 = "crt1.o";
6673f4a2713aSLionel Sambuc }
6674f4a2713aSLionel Sambuc if (crt1)
6675f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crt1)));
6676f4a2713aSLionel Sambuc
6677f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o")));
6678f4a2713aSLionel Sambuc
6679*0a6a1f1dSLionel Sambuc const char *crtbegin = nullptr;
6680f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_static))
6681f4a2713aSLionel Sambuc crtbegin = "crtbeginT.o";
6682*0a6a1f1dSLionel Sambuc else if (Args.hasArg(options::OPT_shared) || IsPIE)
6683f4a2713aSLionel Sambuc crtbegin = "crtbeginS.o";
6684f4a2713aSLionel Sambuc else
6685f4a2713aSLionel Sambuc crtbegin = "crtbegin.o";
6686f4a2713aSLionel Sambuc
6687f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin)));
6688f4a2713aSLionel Sambuc }
6689f4a2713aSLionel Sambuc
6690f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_L);
6691*0a6a1f1dSLionel Sambuc const ToolChain::path_list &Paths = ToolChain.getFilePaths();
6692*0a6a1f1dSLionel Sambuc for (const auto &Path : Paths)
6693*0a6a1f1dSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + Path));
6694f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
6695f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_e);
6696f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_s);
6697f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_t);
6698f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag);
6699f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_r);
6700f4a2713aSLionel Sambuc
6701*0a6a1f1dSLionel Sambuc if (D.IsUsingLTO(Args))
6702*0a6a1f1dSLionel Sambuc AddGoldPlugin(ToolChain, Args, CmdArgs);
6703f4a2713aSLionel Sambuc
6704*0a6a1f1dSLionel Sambuc bool NeedsSanitizerDeps = addSanitizerRuntimes(ToolChain, Args, CmdArgs);
6705f4a2713aSLionel Sambuc AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
6706f4a2713aSLionel Sambuc
6707f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_nostdlib) &&
6708f4a2713aSLionel Sambuc !Args.hasArg(options::OPT_nodefaultlibs)) {
6709f4a2713aSLionel Sambuc if (D.CCCIsCXX()) {
6710f4a2713aSLionel Sambuc ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
6711f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_pg))
6712f4a2713aSLionel Sambuc CmdArgs.push_back("-lm_p");
6713f4a2713aSLionel Sambuc else
6714f4a2713aSLionel Sambuc CmdArgs.push_back("-lm");
6715f4a2713aSLionel Sambuc }
6716*0a6a1f1dSLionel Sambuc if (NeedsSanitizerDeps)
6717*0a6a1f1dSLionel Sambuc linkSanitizerRuntimeDeps(ToolChain, CmdArgs);
6718f4a2713aSLionel Sambuc // FIXME: For some reason GCC passes -lgcc and -lgcc_s before adding
6719f4a2713aSLionel Sambuc // the default system libraries. Just mimic this for now.
6720f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_pg))
6721f4a2713aSLionel Sambuc CmdArgs.push_back("-lgcc_p");
6722f4a2713aSLionel Sambuc else
6723f4a2713aSLionel Sambuc CmdArgs.push_back("-lgcc");
6724f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_static)) {
6725f4a2713aSLionel Sambuc CmdArgs.push_back("-lgcc_eh");
6726f4a2713aSLionel Sambuc } else if (Args.hasArg(options::OPT_pg)) {
6727f4a2713aSLionel Sambuc CmdArgs.push_back("-lgcc_eh_p");
6728f4a2713aSLionel Sambuc } else {
6729f4a2713aSLionel Sambuc CmdArgs.push_back("--as-needed");
6730f4a2713aSLionel Sambuc CmdArgs.push_back("-lgcc_s");
6731f4a2713aSLionel Sambuc CmdArgs.push_back("--no-as-needed");
6732f4a2713aSLionel Sambuc }
6733f4a2713aSLionel Sambuc
6734f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_pthread)) {
6735f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_pg))
6736f4a2713aSLionel Sambuc CmdArgs.push_back("-lpthread_p");
6737f4a2713aSLionel Sambuc else
6738f4a2713aSLionel Sambuc CmdArgs.push_back("-lpthread");
6739f4a2713aSLionel Sambuc }
6740f4a2713aSLionel Sambuc
6741f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_pg)) {
6742f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_shared))
6743f4a2713aSLionel Sambuc CmdArgs.push_back("-lc");
6744f4a2713aSLionel Sambuc else
6745f4a2713aSLionel Sambuc CmdArgs.push_back("-lc_p");
6746f4a2713aSLionel Sambuc CmdArgs.push_back("-lgcc_p");
6747f4a2713aSLionel Sambuc } else {
6748f4a2713aSLionel Sambuc CmdArgs.push_back("-lc");
6749f4a2713aSLionel Sambuc CmdArgs.push_back("-lgcc");
6750f4a2713aSLionel Sambuc }
6751f4a2713aSLionel Sambuc
6752f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_static)) {
6753f4a2713aSLionel Sambuc CmdArgs.push_back("-lgcc_eh");
6754f4a2713aSLionel Sambuc } else if (Args.hasArg(options::OPT_pg)) {
6755f4a2713aSLionel Sambuc CmdArgs.push_back("-lgcc_eh_p");
6756f4a2713aSLionel Sambuc } else {
6757f4a2713aSLionel Sambuc CmdArgs.push_back("--as-needed");
6758f4a2713aSLionel Sambuc CmdArgs.push_back("-lgcc_s");
6759f4a2713aSLionel Sambuc CmdArgs.push_back("--no-as-needed");
6760f4a2713aSLionel Sambuc }
6761f4a2713aSLionel Sambuc }
6762f4a2713aSLionel Sambuc
6763f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_nostdlib) &&
6764f4a2713aSLionel Sambuc !Args.hasArg(options::OPT_nostartfiles)) {
6765*0a6a1f1dSLionel Sambuc if (Args.hasArg(options::OPT_shared) || IsPIE)
6766f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtendS.o")));
6767f4a2713aSLionel Sambuc else
6768f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtend.o")));
6769f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o")));
6770f4a2713aSLionel Sambuc }
6771f4a2713aSLionel Sambuc
6772*0a6a1f1dSLionel Sambuc addProfileRT(ToolChain, Args, CmdArgs);
6773f4a2713aSLionel Sambuc
6774f4a2713aSLionel Sambuc const char *Exec =
6775*0a6a1f1dSLionel Sambuc Args.MakeArgString(getToolChain().GetLinkerPath());
6776*0a6a1f1dSLionel Sambuc C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
6777f4a2713aSLionel Sambuc }
6778f4a2713aSLionel Sambuc
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const6779f4a2713aSLionel Sambuc void netbsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
6780f4a2713aSLionel Sambuc const InputInfo &Output,
6781f4a2713aSLionel Sambuc const InputInfoList &Inputs,
6782f4a2713aSLionel Sambuc const ArgList &Args,
6783f4a2713aSLionel Sambuc const char *LinkingOutput) const {
6784*0a6a1f1dSLionel Sambuc claimNoWarnArgs(Args);
6785f4a2713aSLionel Sambuc ArgStringList CmdArgs;
6786f4a2713aSLionel Sambuc
6787*0a6a1f1dSLionel Sambuc // GNU as needs different flags for creating the correct output format
6788*0a6a1f1dSLionel Sambuc // on architectures with different ABIs or optional feature sets.
6789*0a6a1f1dSLionel Sambuc switch (getToolChain().getArch()) {
6790*0a6a1f1dSLionel Sambuc case llvm::Triple::x86:
6791f4a2713aSLionel Sambuc CmdArgs.push_back("--32");
6792*0a6a1f1dSLionel Sambuc break;
6793*0a6a1f1dSLionel Sambuc case llvm::Triple::arm:
6794*0a6a1f1dSLionel Sambuc case llvm::Triple::armeb:
6795*0a6a1f1dSLionel Sambuc case llvm::Triple::thumb:
6796*0a6a1f1dSLionel Sambuc case llvm::Triple::thumbeb: {
6797*0a6a1f1dSLionel Sambuc std::string MArch(arm::getARMTargetCPU(Args, getToolChain().getTriple()));
6798*0a6a1f1dSLionel Sambuc CmdArgs.push_back(Args.MakeArgString("-mcpu=" + MArch));
6799*0a6a1f1dSLionel Sambuc break;
6800*0a6a1f1dSLionel Sambuc }
6801f4a2713aSLionel Sambuc
6802*0a6a1f1dSLionel Sambuc case llvm::Triple::mips:
6803*0a6a1f1dSLionel Sambuc case llvm::Triple::mipsel:
6804*0a6a1f1dSLionel Sambuc case llvm::Triple::mips64:
6805*0a6a1f1dSLionel Sambuc case llvm::Triple::mips64el: {
6806*0a6a1f1dSLionel Sambuc StringRef CPUName;
6807*0a6a1f1dSLionel Sambuc StringRef ABIName;
6808*0a6a1f1dSLionel Sambuc mips::getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName);
6809*0a6a1f1dSLionel Sambuc
6810*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-march");
6811*0a6a1f1dSLionel Sambuc CmdArgs.push_back(CPUName.data());
6812*0a6a1f1dSLionel Sambuc
6813*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-mabi");
6814*0a6a1f1dSLionel Sambuc CmdArgs.push_back(getGnuCompatibleMipsABIName(ABIName).data());
6815*0a6a1f1dSLionel Sambuc
6816*0a6a1f1dSLionel Sambuc if (getToolChain().getArch() == llvm::Triple::mips ||
6817*0a6a1f1dSLionel Sambuc getToolChain().getArch() == llvm::Triple::mips64)
6818f4a2713aSLionel Sambuc CmdArgs.push_back("-EB");
6819*0a6a1f1dSLionel Sambuc else
6820f4a2713aSLionel Sambuc CmdArgs.push_back("-EL");
6821f4a2713aSLionel Sambuc
6822*0a6a1f1dSLionel Sambuc addAssemblerKPIC(Args, CmdArgs);
6823*0a6a1f1dSLionel Sambuc break;
6824*0a6a1f1dSLionel Sambuc }
6825*0a6a1f1dSLionel Sambuc
6826*0a6a1f1dSLionel Sambuc case llvm::Triple::sparc:
6827*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-32");
6828*0a6a1f1dSLionel Sambuc addAssemblerKPIC(Args, CmdArgs);
6829*0a6a1f1dSLionel Sambuc break;
6830*0a6a1f1dSLionel Sambuc
6831*0a6a1f1dSLionel Sambuc case llvm::Triple::sparcv9:
6832*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-64");
6833*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-Av9");
6834*0a6a1f1dSLionel Sambuc addAssemblerKPIC(Args, CmdArgs);
6835*0a6a1f1dSLionel Sambuc break;
6836*0a6a1f1dSLionel Sambuc
6837*0a6a1f1dSLionel Sambuc default:
6838*0a6a1f1dSLionel Sambuc break;
6839*0a6a1f1dSLionel Sambuc }
6840*0a6a1f1dSLionel Sambuc
6841f4a2713aSLionel Sambuc Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
6842f4a2713aSLionel Sambuc options::OPT_Xassembler);
6843f4a2713aSLionel Sambuc
6844f4a2713aSLionel Sambuc CmdArgs.push_back("-o");
6845f4a2713aSLionel Sambuc CmdArgs.push_back(Output.getFilename());
6846f4a2713aSLionel Sambuc
6847*0a6a1f1dSLionel Sambuc for (const auto &II : Inputs)
6848f4a2713aSLionel Sambuc CmdArgs.push_back(II.getFilename());
6849f4a2713aSLionel Sambuc
6850f4a2713aSLionel Sambuc const char *Exec = Args.MakeArgString((getToolChain().GetProgramPath("as")));
6851*0a6a1f1dSLionel Sambuc C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
6852f4a2713aSLionel Sambuc }
6853f4a2713aSLionel Sambuc
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const6854f4a2713aSLionel Sambuc void netbsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
6855f4a2713aSLionel Sambuc const InputInfo &Output,
6856f4a2713aSLionel Sambuc const InputInfoList &Inputs,
6857f4a2713aSLionel Sambuc const ArgList &Args,
6858f4a2713aSLionel Sambuc const char *LinkingOutput) const {
6859f4a2713aSLionel Sambuc const Driver &D = getToolChain().getDriver();
6860f4a2713aSLionel Sambuc ArgStringList CmdArgs;
6861f4a2713aSLionel Sambuc
6862f4a2713aSLionel Sambuc if (!D.SysRoot.empty())
6863f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
6864f4a2713aSLionel Sambuc
6865*0a6a1f1dSLionel Sambuc CmdArgs.push_back("--eh-frame-hdr");
6866f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_static)) {
6867f4a2713aSLionel Sambuc CmdArgs.push_back("-Bstatic");
6868f4a2713aSLionel Sambuc } else {
6869f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_rdynamic))
6870f4a2713aSLionel Sambuc CmdArgs.push_back("-export-dynamic");
6871f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_shared)) {
6872f4a2713aSLionel Sambuc CmdArgs.push_back("-Bshareable");
6873f4a2713aSLionel Sambuc } else {
6874f4a2713aSLionel Sambuc CmdArgs.push_back("-dynamic-linker");
6875f4a2713aSLionel Sambuc CmdArgs.push_back("/libexec/ld.elf_so");
6876f4a2713aSLionel Sambuc }
6877f4a2713aSLionel Sambuc }
6878f4a2713aSLionel Sambuc
6879*0a6a1f1dSLionel Sambuc // Many NetBSD architectures support more than one ABI.
6880*0a6a1f1dSLionel Sambuc // Determine the correct emulation for ld.
6881*0a6a1f1dSLionel Sambuc switch (getToolChain().getArch()) {
6882*0a6a1f1dSLionel Sambuc case llvm::Triple::x86:
6883f4a2713aSLionel Sambuc CmdArgs.push_back("-m");
6884f4a2713aSLionel Sambuc CmdArgs.push_back("elf_i386");
6885*0a6a1f1dSLionel Sambuc break;
6886*0a6a1f1dSLionel Sambuc case llvm::Triple::arm:
6887*0a6a1f1dSLionel Sambuc case llvm::Triple::thumb:
6888*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-m");
6889*0a6a1f1dSLionel Sambuc switch (getToolChain().getTriple().getEnvironment()) {
6890*0a6a1f1dSLionel Sambuc case llvm::Triple::EABI:
6891*0a6a1f1dSLionel Sambuc case llvm::Triple::GNUEABI:
6892*0a6a1f1dSLionel Sambuc CmdArgs.push_back("armelf_nbsd_eabi");
6893*0a6a1f1dSLionel Sambuc break;
6894*0a6a1f1dSLionel Sambuc case llvm::Triple::EABIHF:
6895*0a6a1f1dSLionel Sambuc case llvm::Triple::GNUEABIHF:
6896*0a6a1f1dSLionel Sambuc CmdArgs.push_back("armelf_nbsd_eabihf");
6897*0a6a1f1dSLionel Sambuc break;
6898*0a6a1f1dSLionel Sambuc default:
6899*0a6a1f1dSLionel Sambuc CmdArgs.push_back("armelf_nbsd");
6900*0a6a1f1dSLionel Sambuc break;
6901*0a6a1f1dSLionel Sambuc }
6902*0a6a1f1dSLionel Sambuc break;
6903*0a6a1f1dSLionel Sambuc case llvm::Triple::armeb:
6904*0a6a1f1dSLionel Sambuc case llvm::Triple::thumbeb:
6905*0a6a1f1dSLionel Sambuc arm::appendEBLinkFlags(Args, CmdArgs, getToolChain().getTriple());
6906*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-m");
6907*0a6a1f1dSLionel Sambuc switch (getToolChain().getTriple().getEnvironment()) {
6908*0a6a1f1dSLionel Sambuc case llvm::Triple::EABI:
6909*0a6a1f1dSLionel Sambuc case llvm::Triple::GNUEABI:
6910*0a6a1f1dSLionel Sambuc CmdArgs.push_back("armelfb_nbsd_eabi");
6911*0a6a1f1dSLionel Sambuc break;
6912*0a6a1f1dSLionel Sambuc case llvm::Triple::EABIHF:
6913*0a6a1f1dSLionel Sambuc case llvm::Triple::GNUEABIHF:
6914*0a6a1f1dSLionel Sambuc CmdArgs.push_back("armelfb_nbsd_eabihf");
6915*0a6a1f1dSLionel Sambuc break;
6916*0a6a1f1dSLionel Sambuc default:
6917*0a6a1f1dSLionel Sambuc CmdArgs.push_back("armelfb_nbsd");
6918*0a6a1f1dSLionel Sambuc break;
6919*0a6a1f1dSLionel Sambuc }
6920*0a6a1f1dSLionel Sambuc break;
6921*0a6a1f1dSLionel Sambuc case llvm::Triple::mips64:
6922*0a6a1f1dSLionel Sambuc case llvm::Triple::mips64el:
6923*0a6a1f1dSLionel Sambuc if (mips::hasMipsAbiArg(Args, "32")) {
6924*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-m");
6925*0a6a1f1dSLionel Sambuc if (getToolChain().getArch() == llvm::Triple::mips64)
6926*0a6a1f1dSLionel Sambuc CmdArgs.push_back("elf32btsmip");
6927*0a6a1f1dSLionel Sambuc else
6928*0a6a1f1dSLionel Sambuc CmdArgs.push_back("elf32ltsmip");
6929*0a6a1f1dSLionel Sambuc } else if (mips::hasMipsAbiArg(Args, "64")) {
6930*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-m");
6931*0a6a1f1dSLionel Sambuc if (getToolChain().getArch() == llvm::Triple::mips64)
6932*0a6a1f1dSLionel Sambuc CmdArgs.push_back("elf64btsmip");
6933*0a6a1f1dSLionel Sambuc else
6934*0a6a1f1dSLionel Sambuc CmdArgs.push_back("elf64ltsmip");
6935*0a6a1f1dSLionel Sambuc }
6936*0a6a1f1dSLionel Sambuc break;
6937*0a6a1f1dSLionel Sambuc case llvm::Triple::ppc:
6938*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-m");
6939*0a6a1f1dSLionel Sambuc CmdArgs.push_back("elf32ppc_nbsd");
6940*0a6a1f1dSLionel Sambuc break;
6941*0a6a1f1dSLionel Sambuc
6942*0a6a1f1dSLionel Sambuc case llvm::Triple::ppc64:
6943*0a6a1f1dSLionel Sambuc case llvm::Triple::ppc64le:
6944*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-m");
6945*0a6a1f1dSLionel Sambuc CmdArgs.push_back("elf64ppc");
6946*0a6a1f1dSLionel Sambuc break;
6947*0a6a1f1dSLionel Sambuc
6948*0a6a1f1dSLionel Sambuc case llvm::Triple::sparc:
6949*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-m");
6950*0a6a1f1dSLionel Sambuc CmdArgs.push_back("elf32_sparc");
6951*0a6a1f1dSLionel Sambuc break;
6952*0a6a1f1dSLionel Sambuc
6953*0a6a1f1dSLionel Sambuc case llvm::Triple::sparcv9:
6954*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-m");
6955*0a6a1f1dSLionel Sambuc CmdArgs.push_back("elf64_sparc");
6956*0a6a1f1dSLionel Sambuc break;
6957*0a6a1f1dSLionel Sambuc
6958*0a6a1f1dSLionel Sambuc default:
6959*0a6a1f1dSLionel Sambuc break;
6960f4a2713aSLionel Sambuc }
6961f4a2713aSLionel Sambuc
6962f4a2713aSLionel Sambuc if (Output.isFilename()) {
6963f4a2713aSLionel Sambuc CmdArgs.push_back("-o");
6964f4a2713aSLionel Sambuc CmdArgs.push_back(Output.getFilename());
6965f4a2713aSLionel Sambuc } else {
6966f4a2713aSLionel Sambuc assert(Output.isNothing() && "Invalid output.");
6967f4a2713aSLionel Sambuc }
6968f4a2713aSLionel Sambuc
6969f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_nostdlib) &&
6970f4a2713aSLionel Sambuc !Args.hasArg(options::OPT_nostartfiles)) {
6971f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_shared)) {
6972f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(
6973f4a2713aSLionel Sambuc getToolChain().GetFilePath("crt0.o")));
6974f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(
6975f4a2713aSLionel Sambuc getToolChain().GetFilePath("crti.o")));
6976f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(
6977f4a2713aSLionel Sambuc getToolChain().GetFilePath("crtbegin.o")));
6978f4a2713aSLionel Sambuc } else {
6979f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(
6980f4a2713aSLionel Sambuc getToolChain().GetFilePath("crti.o")));
6981f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(
6982f4a2713aSLionel Sambuc getToolChain().GetFilePath("crtbeginS.o")));
6983f4a2713aSLionel Sambuc }
6984f4a2713aSLionel Sambuc }
6985f4a2713aSLionel Sambuc
6986f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_L);
6987f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
6988f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_e);
6989f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_s);
6990f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_t);
6991f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag);
6992f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_r);
6993f4a2713aSLionel Sambuc
6994f4a2713aSLionel Sambuc AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
6995f4a2713aSLionel Sambuc
6996f4a2713aSLionel Sambuc unsigned Major, Minor, Micro;
6997f4a2713aSLionel Sambuc getToolChain().getTriple().getOSVersion(Major, Minor, Micro);
6998f4a2713aSLionel Sambuc bool useLibgcc = true;
6999*0a6a1f1dSLionel Sambuc if (Major >= 7 || (Major == 6 && Minor == 99 && Micro >= 49) || Major == 0) {
7000*0a6a1f1dSLionel Sambuc switch(getToolChain().getArch()) {
7001*0a6a1f1dSLionel Sambuc case llvm::Triple::aarch64:
7002*0a6a1f1dSLionel Sambuc case llvm::Triple::arm:
7003*0a6a1f1dSLionel Sambuc case llvm::Triple::armeb:
7004*0a6a1f1dSLionel Sambuc case llvm::Triple::thumb:
7005*0a6a1f1dSLionel Sambuc case llvm::Triple::thumbeb:
7006*0a6a1f1dSLionel Sambuc case llvm::Triple::ppc:
7007*0a6a1f1dSLionel Sambuc case llvm::Triple::ppc64:
7008*0a6a1f1dSLionel Sambuc case llvm::Triple::ppc64le:
7009*0a6a1f1dSLionel Sambuc case llvm::Triple::x86:
7010*0a6a1f1dSLionel Sambuc case llvm::Triple::x86_64:
7011f4a2713aSLionel Sambuc useLibgcc = false;
7012*0a6a1f1dSLionel Sambuc break;
7013*0a6a1f1dSLionel Sambuc default:
7014*0a6a1f1dSLionel Sambuc break;
7015*0a6a1f1dSLionel Sambuc }
7016f4a2713aSLionel Sambuc }
7017f4a2713aSLionel Sambuc
7018f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_nostdlib) &&
7019f4a2713aSLionel Sambuc !Args.hasArg(options::OPT_nodefaultlibs)) {
7020f4a2713aSLionel Sambuc if (D.CCCIsCXX()) {
7021f4a2713aSLionel Sambuc getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
7022f4a2713aSLionel Sambuc CmdArgs.push_back("-lm");
7023f4a2713aSLionel Sambuc }
7024f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_pthread))
7025f4a2713aSLionel Sambuc CmdArgs.push_back("-lpthread");
7026f4a2713aSLionel Sambuc CmdArgs.push_back("-lc");
7027f4a2713aSLionel Sambuc
7028f4a2713aSLionel Sambuc if (useLibgcc) {
7029f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_static)) {
7030f4a2713aSLionel Sambuc // libgcc_eh depends on libc, so resolve as much as possible,
7031f4a2713aSLionel Sambuc // pull in any new requirements from libc and then get the rest
7032f4a2713aSLionel Sambuc // of libgcc.
7033f4a2713aSLionel Sambuc CmdArgs.push_back("-lgcc_eh");
7034f4a2713aSLionel Sambuc CmdArgs.push_back("-lc");
7035f4a2713aSLionel Sambuc CmdArgs.push_back("-lgcc");
7036f4a2713aSLionel Sambuc } else {
7037f4a2713aSLionel Sambuc CmdArgs.push_back("-lgcc");
7038f4a2713aSLionel Sambuc CmdArgs.push_back("--as-needed");
7039f4a2713aSLionel Sambuc CmdArgs.push_back("-lgcc_s");
7040f4a2713aSLionel Sambuc CmdArgs.push_back("--no-as-needed");
7041f4a2713aSLionel Sambuc }
7042f4a2713aSLionel Sambuc }
7043f4a2713aSLionel Sambuc }
7044f4a2713aSLionel Sambuc
7045f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_nostdlib) &&
7046f4a2713aSLionel Sambuc !Args.hasArg(options::OPT_nostartfiles)) {
7047f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_shared))
7048f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(
7049f4a2713aSLionel Sambuc "crtend.o")));
7050f4a2713aSLionel Sambuc else
7051f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(
7052f4a2713aSLionel Sambuc "crtendS.o")));
7053f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(
7054f4a2713aSLionel Sambuc "crtn.o")));
7055f4a2713aSLionel Sambuc }
7056f4a2713aSLionel Sambuc
7057*0a6a1f1dSLionel Sambuc addProfileRT(getToolChain(), Args, CmdArgs);
7058f4a2713aSLionel Sambuc
7059*0a6a1f1dSLionel Sambuc const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
7060*0a6a1f1dSLionel Sambuc C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
7061f4a2713aSLionel Sambuc }
7062f4a2713aSLionel Sambuc
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const7063f4a2713aSLionel Sambuc void gnutools::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
7064f4a2713aSLionel Sambuc const InputInfo &Output,
7065f4a2713aSLionel Sambuc const InputInfoList &Inputs,
7066f4a2713aSLionel Sambuc const ArgList &Args,
7067f4a2713aSLionel Sambuc const char *LinkingOutput) const {
7068*0a6a1f1dSLionel Sambuc claimNoWarnArgs(Args);
7069*0a6a1f1dSLionel Sambuc
7070f4a2713aSLionel Sambuc ArgStringList CmdArgs;
7071*0a6a1f1dSLionel Sambuc bool NeedsKPIC = false;
7072f4a2713aSLionel Sambuc
7073f4a2713aSLionel Sambuc // Add --32/--64 to make sure we get the format we want.
7074f4a2713aSLionel Sambuc // This is incomplete
7075f4a2713aSLionel Sambuc if (getToolChain().getArch() == llvm::Triple::x86) {
7076f4a2713aSLionel Sambuc CmdArgs.push_back("--32");
7077f4a2713aSLionel Sambuc } else if (getToolChain().getArch() == llvm::Triple::x86_64) {
7078*0a6a1f1dSLionel Sambuc if (getToolChain().getTriple().getEnvironment() == llvm::Triple::GNUX32)
7079*0a6a1f1dSLionel Sambuc CmdArgs.push_back("--x32");
7080*0a6a1f1dSLionel Sambuc else
7081f4a2713aSLionel Sambuc CmdArgs.push_back("--64");
7082f4a2713aSLionel Sambuc } else if (getToolChain().getArch() == llvm::Triple::ppc) {
7083f4a2713aSLionel Sambuc CmdArgs.push_back("-a32");
7084f4a2713aSLionel Sambuc CmdArgs.push_back("-mppc");
7085f4a2713aSLionel Sambuc CmdArgs.push_back("-many");
7086f4a2713aSLionel Sambuc } else if (getToolChain().getArch() == llvm::Triple::ppc64) {
7087f4a2713aSLionel Sambuc CmdArgs.push_back("-a64");
7088f4a2713aSLionel Sambuc CmdArgs.push_back("-mppc64");
7089f4a2713aSLionel Sambuc CmdArgs.push_back("-many");
7090f4a2713aSLionel Sambuc } else if (getToolChain().getArch() == llvm::Triple::ppc64le) {
7091f4a2713aSLionel Sambuc CmdArgs.push_back("-a64");
7092*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-mppc64");
7093f4a2713aSLionel Sambuc CmdArgs.push_back("-many");
7094*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-mlittle-endian");
7095*0a6a1f1dSLionel Sambuc } else if (getToolChain().getArch() == llvm::Triple::sparc) {
7096*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-32");
7097*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-Av8plusa");
7098*0a6a1f1dSLionel Sambuc NeedsKPIC = true;
7099*0a6a1f1dSLionel Sambuc } else if (getToolChain().getArch() == llvm::Triple::sparcv9) {
7100*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-64");
7101*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-Av9a");
7102*0a6a1f1dSLionel Sambuc NeedsKPIC = true;
7103*0a6a1f1dSLionel Sambuc } else if (getToolChain().getArch() == llvm::Triple::arm ||
7104*0a6a1f1dSLionel Sambuc getToolChain().getArch() == llvm::Triple::armeb) {
7105f4a2713aSLionel Sambuc StringRef MArch = getToolChain().getArchName();
7106f4a2713aSLionel Sambuc if (MArch == "armv7" || MArch == "armv7a" || MArch == "armv7-a")
7107f4a2713aSLionel Sambuc CmdArgs.push_back("-mfpu=neon");
7108*0a6a1f1dSLionel Sambuc if (MArch == "armv8" || MArch == "armv8a" || MArch == "armv8-a" ||
7109*0a6a1f1dSLionel Sambuc MArch == "armebv8" || MArch == "armebv8a" || MArch == "armebv8-a")
7110f4a2713aSLionel Sambuc CmdArgs.push_back("-mfpu=crypto-neon-fp-armv8");
7111f4a2713aSLionel Sambuc
7112*0a6a1f1dSLionel Sambuc StringRef ARMFloatABI = tools::arm::getARMFloatABI(
7113*0a6a1f1dSLionel Sambuc getToolChain().getDriver(), Args, getToolChain().getTriple());
7114f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString("-mfloat-abi=" + ARMFloatABI));
7115f4a2713aSLionel Sambuc
7116f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_march_EQ);
7117*0a6a1f1dSLionel Sambuc
7118*0a6a1f1dSLionel Sambuc // FIXME: remove krait check when GNU tools support krait cpu
7119*0a6a1f1dSLionel Sambuc // for now replace it with -march=armv7-a to avoid a lower
7120*0a6a1f1dSLionel Sambuc // march from being picked in the absence of a cpu flag.
7121*0a6a1f1dSLionel Sambuc Arg *A;
7122*0a6a1f1dSLionel Sambuc if ((A = Args.getLastArg(options::OPT_mcpu_EQ)) &&
7123*0a6a1f1dSLionel Sambuc StringRef(A->getValue()) == "krait")
7124*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-march=armv7-a");
7125*0a6a1f1dSLionel Sambuc else
7126f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_mcpu_EQ);
7127f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_mfpu_EQ);
7128f4a2713aSLionel Sambuc } else if (getToolChain().getArch() == llvm::Triple::mips ||
7129f4a2713aSLionel Sambuc getToolChain().getArch() == llvm::Triple::mipsel ||
7130f4a2713aSLionel Sambuc getToolChain().getArch() == llvm::Triple::mips64 ||
7131f4a2713aSLionel Sambuc getToolChain().getArch() == llvm::Triple::mips64el) {
7132f4a2713aSLionel Sambuc StringRef CPUName;
7133f4a2713aSLionel Sambuc StringRef ABIName;
7134*0a6a1f1dSLionel Sambuc mips::getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName);
7135*0a6a1f1dSLionel Sambuc ABIName = getGnuCompatibleMipsABIName(ABIName);
7136f4a2713aSLionel Sambuc
7137f4a2713aSLionel Sambuc CmdArgs.push_back("-march");
7138f4a2713aSLionel Sambuc CmdArgs.push_back(CPUName.data());
7139f4a2713aSLionel Sambuc
7140f4a2713aSLionel Sambuc CmdArgs.push_back("-mabi");
7141*0a6a1f1dSLionel Sambuc CmdArgs.push_back(ABIName.data());
7142*0a6a1f1dSLionel Sambuc
7143*0a6a1f1dSLionel Sambuc // -mno-shared should be emitted unless -fpic, -fpie, -fPIC, -fPIE,
7144*0a6a1f1dSLionel Sambuc // or -mshared (not implemented) is in effect.
7145*0a6a1f1dSLionel Sambuc bool IsPicOrPie = false;
7146*0a6a1f1dSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC,
7147*0a6a1f1dSLionel Sambuc options::OPT_fpic, options::OPT_fno_pic,
7148*0a6a1f1dSLionel Sambuc options::OPT_fPIE, options::OPT_fno_PIE,
7149*0a6a1f1dSLionel Sambuc options::OPT_fpie, options::OPT_fno_pie)) {
7150*0a6a1f1dSLionel Sambuc if (A->getOption().matches(options::OPT_fPIC) ||
7151*0a6a1f1dSLionel Sambuc A->getOption().matches(options::OPT_fpic) ||
7152*0a6a1f1dSLionel Sambuc A->getOption().matches(options::OPT_fPIE) ||
7153*0a6a1f1dSLionel Sambuc A->getOption().matches(options::OPT_fpie))
7154*0a6a1f1dSLionel Sambuc IsPicOrPie = true;
7155*0a6a1f1dSLionel Sambuc }
7156*0a6a1f1dSLionel Sambuc if (!IsPicOrPie)
7157*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-mno-shared");
7158*0a6a1f1dSLionel Sambuc
7159*0a6a1f1dSLionel Sambuc // LLVM doesn't support -mplt yet and acts as if it is always given.
7160*0a6a1f1dSLionel Sambuc // However, -mplt has no effect with the N64 ABI.
7161*0a6a1f1dSLionel Sambuc CmdArgs.push_back(ABIName == "64" ? "-KPIC" : "-call_nonpic");
7162f4a2713aSLionel Sambuc
7163f4a2713aSLionel Sambuc if (getToolChain().getArch() == llvm::Triple::mips ||
7164f4a2713aSLionel Sambuc getToolChain().getArch() == llvm::Triple::mips64)
7165f4a2713aSLionel Sambuc CmdArgs.push_back("-EB");
7166f4a2713aSLionel Sambuc else
7167f4a2713aSLionel Sambuc CmdArgs.push_back("-EL");
7168f4a2713aSLionel Sambuc
7169f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_mnan_EQ)) {
7170f4a2713aSLionel Sambuc if (StringRef(A->getValue()) == "2008")
7171f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString("-mnan=2008"));
7172f4a2713aSLionel Sambuc }
7173f4a2713aSLionel Sambuc
7174*0a6a1f1dSLionel Sambuc // Add the last -mfp32/-mfpxx/-mfp64 or -mfpxx if it is enabled by default.
7175*0a6a1f1dSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_mfp32, options::OPT_mfpxx,
7176*0a6a1f1dSLionel Sambuc options::OPT_mfp64)) {
7177*0a6a1f1dSLionel Sambuc A->claim();
7178*0a6a1f1dSLionel Sambuc A->render(Args, CmdArgs);
7179*0a6a1f1dSLionel Sambuc } else if (mips::isFPXXDefault(getToolChain().getTriple(), CPUName,
7180*0a6a1f1dSLionel Sambuc ABIName))
7181*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-mfpxx");
7182*0a6a1f1dSLionel Sambuc
7183*0a6a1f1dSLionel Sambuc // Pass on -mmips16 or -mno-mips16. However, the assembler equivalent of
7184*0a6a1f1dSLionel Sambuc // -mno-mips16 is actually -no-mips16.
7185*0a6a1f1dSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_mips16,
7186*0a6a1f1dSLionel Sambuc options::OPT_mno_mips16)) {
7187*0a6a1f1dSLionel Sambuc if (A->getOption().matches(options::OPT_mips16)) {
7188*0a6a1f1dSLionel Sambuc A->claim();
7189*0a6a1f1dSLionel Sambuc A->render(Args, CmdArgs);
7190*0a6a1f1dSLionel Sambuc } else {
7191*0a6a1f1dSLionel Sambuc A->claim();
7192*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-no-mips16");
7193*0a6a1f1dSLionel Sambuc }
7194*0a6a1f1dSLionel Sambuc }
7195*0a6a1f1dSLionel Sambuc
7196f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_mmicromips,
7197f4a2713aSLionel Sambuc options::OPT_mno_micromips);
7198f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_mdsp, options::OPT_mno_dsp);
7199f4a2713aSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_mdspr2, options::OPT_mno_dspr2);
7200f4a2713aSLionel Sambuc
7201*0a6a1f1dSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_mmsa, options::OPT_mno_msa)) {
7202*0a6a1f1dSLionel Sambuc // Do not use AddLastArg because not all versions of MIPS assembler
7203*0a6a1f1dSLionel Sambuc // support -mmsa / -mno-msa options.
7204*0a6a1f1dSLionel Sambuc if (A->getOption().matches(options::OPT_mmsa))
7205*0a6a1f1dSLionel Sambuc CmdArgs.push_back(Args.MakeArgString("-mmsa"));
7206f4a2713aSLionel Sambuc }
7207*0a6a1f1dSLionel Sambuc
7208*0a6a1f1dSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_mhard_float,
7209*0a6a1f1dSLionel Sambuc options::OPT_msoft_float);
7210*0a6a1f1dSLionel Sambuc
7211*0a6a1f1dSLionel Sambuc Args.AddLastArg(CmdArgs, options::OPT_modd_spreg,
7212*0a6a1f1dSLionel Sambuc options::OPT_mno_odd_spreg);
7213*0a6a1f1dSLionel Sambuc
7214*0a6a1f1dSLionel Sambuc NeedsKPIC = true;
7215f4a2713aSLionel Sambuc } else if (getToolChain().getArch() == llvm::Triple::systemz) {
7216f4a2713aSLionel Sambuc // Always pass an -march option, since our default of z10 is later
7217f4a2713aSLionel Sambuc // than the GNU assembler's default.
7218f4a2713aSLionel Sambuc StringRef CPUName = getSystemZTargetCPU(Args);
7219f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString("-march=" + CPUName));
7220f4a2713aSLionel Sambuc }
7221f4a2713aSLionel Sambuc
7222*0a6a1f1dSLionel Sambuc if (NeedsKPIC)
7223*0a6a1f1dSLionel Sambuc addAssemblerKPIC(Args, CmdArgs);
7224*0a6a1f1dSLionel Sambuc
7225f4a2713aSLionel Sambuc Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
7226f4a2713aSLionel Sambuc options::OPT_Xassembler);
7227f4a2713aSLionel Sambuc
7228f4a2713aSLionel Sambuc CmdArgs.push_back("-o");
7229f4a2713aSLionel Sambuc CmdArgs.push_back(Output.getFilename());
7230f4a2713aSLionel Sambuc
7231*0a6a1f1dSLionel Sambuc for (const auto &II : Inputs)
7232f4a2713aSLionel Sambuc CmdArgs.push_back(II.getFilename());
7233f4a2713aSLionel Sambuc
7234*0a6a1f1dSLionel Sambuc const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
7235*0a6a1f1dSLionel Sambuc C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
7236f4a2713aSLionel Sambuc
7237f4a2713aSLionel Sambuc // Handle the debug info splitting at object creation time if we're
7238f4a2713aSLionel Sambuc // creating an object.
7239f4a2713aSLionel Sambuc // TODO: Currently only works on linux with newer objcopy.
7240f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_gsplit_dwarf) &&
7241f4a2713aSLionel Sambuc getToolChain().getTriple().isOSLinux())
7242f4a2713aSLionel Sambuc SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output,
7243f4a2713aSLionel Sambuc SplitDebugName(Args, Inputs));
7244f4a2713aSLionel Sambuc }
7245f4a2713aSLionel Sambuc
AddLibgcc(const llvm::Triple & Triple,const Driver & D,ArgStringList & CmdArgs,const ArgList & Args)7246*0a6a1f1dSLionel Sambuc static void AddLibgcc(const llvm::Triple &Triple, const Driver &D,
7247f4a2713aSLionel Sambuc ArgStringList &CmdArgs, const ArgList &Args) {
7248f4a2713aSLionel Sambuc bool isAndroid = Triple.getEnvironment() == llvm::Triple::Android;
7249f4a2713aSLionel Sambuc bool StaticLibgcc = Args.hasArg(options::OPT_static_libgcc) ||
7250f4a2713aSLionel Sambuc Args.hasArg(options::OPT_static);
7251f4a2713aSLionel Sambuc if (!D.CCCIsCXX())
7252f4a2713aSLionel Sambuc CmdArgs.push_back("-lgcc");
7253f4a2713aSLionel Sambuc
7254f4a2713aSLionel Sambuc if (StaticLibgcc || isAndroid) {
7255f4a2713aSLionel Sambuc if (D.CCCIsCXX())
7256f4a2713aSLionel Sambuc CmdArgs.push_back("-lgcc");
7257f4a2713aSLionel Sambuc } else {
7258f4a2713aSLionel Sambuc if (!D.CCCIsCXX())
7259f4a2713aSLionel Sambuc CmdArgs.push_back("--as-needed");
7260f4a2713aSLionel Sambuc CmdArgs.push_back("-lgcc_s");
7261f4a2713aSLionel Sambuc if (!D.CCCIsCXX())
7262f4a2713aSLionel Sambuc CmdArgs.push_back("--no-as-needed");
7263f4a2713aSLionel Sambuc }
7264f4a2713aSLionel Sambuc
7265f4a2713aSLionel Sambuc if (StaticLibgcc && !isAndroid)
7266f4a2713aSLionel Sambuc CmdArgs.push_back("-lgcc_eh");
7267f4a2713aSLionel Sambuc else if (!Args.hasArg(options::OPT_shared) && D.CCCIsCXX())
7268f4a2713aSLionel Sambuc CmdArgs.push_back("-lgcc");
7269f4a2713aSLionel Sambuc
7270f4a2713aSLionel Sambuc // According to Android ABI, we have to link with libdl if we are
7271f4a2713aSLionel Sambuc // linking with non-static libgcc.
7272f4a2713aSLionel Sambuc //
7273f4a2713aSLionel Sambuc // NOTE: This fixes a link error on Android MIPS as well. The non-static
7274f4a2713aSLionel Sambuc // libgcc for MIPS relies on _Unwind_Find_FDE and dl_iterate_phdr from libdl.
7275f4a2713aSLionel Sambuc if (isAndroid && !StaticLibgcc)
7276f4a2713aSLionel Sambuc CmdArgs.push_back("-ldl");
7277f4a2713aSLionel Sambuc }
7278f4a2713aSLionel Sambuc
getLinuxDynamicLinker(const ArgList & Args,const toolchains::Linux & ToolChain)7279*0a6a1f1dSLionel Sambuc static std::string getLinuxDynamicLinker(const ArgList &Args,
7280f4a2713aSLionel Sambuc const toolchains::Linux &ToolChain) {
7281*0a6a1f1dSLionel Sambuc if (ToolChain.getTriple().getEnvironment() == llvm::Triple::Android) {
7282*0a6a1f1dSLionel Sambuc if (ToolChain.getTriple().isArch64Bit())
7283*0a6a1f1dSLionel Sambuc return "/system/bin/linker64";
7284*0a6a1f1dSLionel Sambuc else
7285f4a2713aSLionel Sambuc return "/system/bin/linker";
7286*0a6a1f1dSLionel Sambuc } else if (ToolChain.getArch() == llvm::Triple::x86 ||
7287*0a6a1f1dSLionel Sambuc ToolChain.getArch() == llvm::Triple::sparc)
7288f4a2713aSLionel Sambuc return "/lib/ld-linux.so.2";
7289f4a2713aSLionel Sambuc else if (ToolChain.getArch() == llvm::Triple::aarch64)
7290f4a2713aSLionel Sambuc return "/lib/ld-linux-aarch64.so.1";
7291*0a6a1f1dSLionel Sambuc else if (ToolChain.getArch() == llvm::Triple::aarch64_be)
7292*0a6a1f1dSLionel Sambuc return "/lib/ld-linux-aarch64_be.so.1";
7293f4a2713aSLionel Sambuc else if (ToolChain.getArch() == llvm::Triple::arm ||
7294f4a2713aSLionel Sambuc ToolChain.getArch() == llvm::Triple::thumb) {
7295f4a2713aSLionel Sambuc if (ToolChain.getTriple().getEnvironment() == llvm::Triple::GNUEABIHF)
7296f4a2713aSLionel Sambuc return "/lib/ld-linux-armhf.so.3";
7297f4a2713aSLionel Sambuc else
7298f4a2713aSLionel Sambuc return "/lib/ld-linux.so.3";
7299*0a6a1f1dSLionel Sambuc } else if (ToolChain.getArch() == llvm::Triple::armeb ||
7300*0a6a1f1dSLionel Sambuc ToolChain.getArch() == llvm::Triple::thumbeb) {
7301*0a6a1f1dSLionel Sambuc if (ToolChain.getTriple().getEnvironment() == llvm::Triple::GNUEABIHF)
7302*0a6a1f1dSLionel Sambuc return "/lib/ld-linux-armhf.so.3"; /* TODO: check which dynamic linker name. */
7303f4a2713aSLionel Sambuc else
7304*0a6a1f1dSLionel Sambuc return "/lib/ld-linux.so.3"; /* TODO: check which dynamic linker name. */
7305*0a6a1f1dSLionel Sambuc } else if (ToolChain.getArch() == llvm::Triple::mips ||
7306*0a6a1f1dSLionel Sambuc ToolChain.getArch() == llvm::Triple::mipsel ||
7307*0a6a1f1dSLionel Sambuc ToolChain.getArch() == llvm::Triple::mips64 ||
7308*0a6a1f1dSLionel Sambuc ToolChain.getArch() == llvm::Triple::mips64el) {
7309*0a6a1f1dSLionel Sambuc StringRef CPUName;
7310*0a6a1f1dSLionel Sambuc StringRef ABIName;
7311*0a6a1f1dSLionel Sambuc mips::getMipsCPUAndABI(Args, ToolChain.getTriple(), CPUName, ABIName);
7312*0a6a1f1dSLionel Sambuc bool IsNaN2008 = mips::isNaN2008(Args, ToolChain.getTriple());
7313*0a6a1f1dSLionel Sambuc
7314*0a6a1f1dSLionel Sambuc StringRef LibDir = llvm::StringSwitch<llvm::StringRef>(ABIName)
7315*0a6a1f1dSLionel Sambuc .Case("o32", "/lib")
7316*0a6a1f1dSLionel Sambuc .Case("n32", "/lib32")
7317*0a6a1f1dSLionel Sambuc .Case("n64", "/lib64")
7318*0a6a1f1dSLionel Sambuc .Default("/lib");
7319*0a6a1f1dSLionel Sambuc StringRef LibName;
7320*0a6a1f1dSLionel Sambuc if (mips::isUCLibc(Args))
7321*0a6a1f1dSLionel Sambuc LibName = IsNaN2008 ? "ld-uClibc-mipsn8.so.0" : "ld-uClibc.so.0";
7322*0a6a1f1dSLionel Sambuc else
7323*0a6a1f1dSLionel Sambuc LibName = IsNaN2008 ? "ld-linux-mipsn8.so.1" : "ld.so.1";
7324*0a6a1f1dSLionel Sambuc
7325*0a6a1f1dSLionel Sambuc return (LibDir + "/" + LibName).str();
7326f4a2713aSLionel Sambuc } else if (ToolChain.getArch() == llvm::Triple::ppc)
7327f4a2713aSLionel Sambuc return "/lib/ld.so.1";
7328*0a6a1f1dSLionel Sambuc else if (ToolChain.getArch() == llvm::Triple::ppc64) {
7329*0a6a1f1dSLionel Sambuc if (ppc::hasPPCAbiArg(Args, "elfv2"))
7330*0a6a1f1dSLionel Sambuc return "/lib64/ld64.so.2";
7331f4a2713aSLionel Sambuc return "/lib64/ld64.so.1";
7332*0a6a1f1dSLionel Sambuc } else if (ToolChain.getArch() == llvm::Triple::ppc64le) {
7333*0a6a1f1dSLionel Sambuc if (ppc::hasPPCAbiArg(Args, "elfv1"))
7334*0a6a1f1dSLionel Sambuc return "/lib64/ld64.so.1";
7335*0a6a1f1dSLionel Sambuc return "/lib64/ld64.so.2";
7336*0a6a1f1dSLionel Sambuc } else if (ToolChain.getArch() == llvm::Triple::systemz)
7337*0a6a1f1dSLionel Sambuc return "/lib64/ld64.so.1";
7338*0a6a1f1dSLionel Sambuc else if (ToolChain.getArch() == llvm::Triple::sparcv9)
7339*0a6a1f1dSLionel Sambuc return "/lib64/ld-linux.so.2";
7340*0a6a1f1dSLionel Sambuc else if (ToolChain.getArch() == llvm::Triple::x86_64 &&
7341*0a6a1f1dSLionel Sambuc ToolChain.getTriple().getEnvironment() == llvm::Triple::GNUX32)
7342*0a6a1f1dSLionel Sambuc return "/libx32/ld-linux-x32.so.2";
7343f4a2713aSLionel Sambuc else
7344f4a2713aSLionel Sambuc return "/lib64/ld-linux-x86-64.so.2";
7345f4a2713aSLionel Sambuc }
7346f4a2713aSLionel Sambuc
AddRunTimeLibs(const ToolChain & TC,const Driver & D,ArgStringList & CmdArgs,const ArgList & Args)7347*0a6a1f1dSLionel Sambuc static void AddRunTimeLibs(const ToolChain &TC, const Driver &D,
7348*0a6a1f1dSLionel Sambuc ArgStringList &CmdArgs, const ArgList &Args) {
7349*0a6a1f1dSLionel Sambuc // Make use of compiler-rt if --rtlib option is used
7350*0a6a1f1dSLionel Sambuc ToolChain::RuntimeLibType RLT = TC.GetRuntimeLibType(Args);
7351*0a6a1f1dSLionel Sambuc
7352*0a6a1f1dSLionel Sambuc switch (RLT) {
7353*0a6a1f1dSLionel Sambuc case ToolChain::RLT_CompilerRT:
7354*0a6a1f1dSLionel Sambuc switch (TC.getTriple().getOS()) {
7355*0a6a1f1dSLionel Sambuc default: llvm_unreachable("unsupported OS");
7356*0a6a1f1dSLionel Sambuc case llvm::Triple::Win32:
7357*0a6a1f1dSLionel Sambuc case llvm::Triple::Linux:
7358*0a6a1f1dSLionel Sambuc addClangRT(TC, Args, CmdArgs);
7359*0a6a1f1dSLionel Sambuc break;
7360*0a6a1f1dSLionel Sambuc }
7361*0a6a1f1dSLionel Sambuc break;
7362*0a6a1f1dSLionel Sambuc case ToolChain::RLT_Libgcc:
7363*0a6a1f1dSLionel Sambuc AddLibgcc(TC.getTriple(), D, CmdArgs, Args);
7364*0a6a1f1dSLionel Sambuc break;
7365*0a6a1f1dSLionel Sambuc }
7366*0a6a1f1dSLionel Sambuc }
7367*0a6a1f1dSLionel Sambuc
getLDMOption(const llvm::Triple & T,const ArgList & Args)7368*0a6a1f1dSLionel Sambuc static const char *getLDMOption(const llvm::Triple &T, const ArgList &Args) {
7369*0a6a1f1dSLionel Sambuc switch (T.getArch()) {
7370*0a6a1f1dSLionel Sambuc case llvm::Triple::x86:
7371*0a6a1f1dSLionel Sambuc return "elf_i386";
7372*0a6a1f1dSLionel Sambuc case llvm::Triple::aarch64:
7373*0a6a1f1dSLionel Sambuc return "aarch64linux";
7374*0a6a1f1dSLionel Sambuc case llvm::Triple::aarch64_be:
7375*0a6a1f1dSLionel Sambuc return "aarch64_be_linux";
7376*0a6a1f1dSLionel Sambuc case llvm::Triple::arm:
7377*0a6a1f1dSLionel Sambuc case llvm::Triple::thumb:
7378*0a6a1f1dSLionel Sambuc return "armelf_linux_eabi";
7379*0a6a1f1dSLionel Sambuc case llvm::Triple::armeb:
7380*0a6a1f1dSLionel Sambuc case llvm::Triple::thumbeb:
7381*0a6a1f1dSLionel Sambuc return "armebelf_linux_eabi"; /* TODO: check which NAME. */
7382*0a6a1f1dSLionel Sambuc case llvm::Triple::ppc:
7383*0a6a1f1dSLionel Sambuc return "elf32ppclinux";
7384*0a6a1f1dSLionel Sambuc case llvm::Triple::ppc64:
7385*0a6a1f1dSLionel Sambuc return "elf64ppc";
7386*0a6a1f1dSLionel Sambuc case llvm::Triple::ppc64le:
7387*0a6a1f1dSLionel Sambuc return "elf64lppc";
7388*0a6a1f1dSLionel Sambuc case llvm::Triple::sparc:
7389*0a6a1f1dSLionel Sambuc return "elf32_sparc";
7390*0a6a1f1dSLionel Sambuc case llvm::Triple::sparcv9:
7391*0a6a1f1dSLionel Sambuc return "elf64_sparc";
7392*0a6a1f1dSLionel Sambuc case llvm::Triple::mips:
7393*0a6a1f1dSLionel Sambuc return "elf32btsmip";
7394*0a6a1f1dSLionel Sambuc case llvm::Triple::mipsel:
7395*0a6a1f1dSLionel Sambuc return "elf32ltsmip";
7396*0a6a1f1dSLionel Sambuc case llvm::Triple::mips64:
7397*0a6a1f1dSLionel Sambuc if (mips::hasMipsAbiArg(Args, "n32"))
7398*0a6a1f1dSLionel Sambuc return "elf32btsmipn32";
7399*0a6a1f1dSLionel Sambuc return "elf64btsmip";
7400*0a6a1f1dSLionel Sambuc case llvm::Triple::mips64el:
7401*0a6a1f1dSLionel Sambuc if (mips::hasMipsAbiArg(Args, "n32"))
7402*0a6a1f1dSLionel Sambuc return "elf32ltsmipn32";
7403*0a6a1f1dSLionel Sambuc return "elf64ltsmip";
7404*0a6a1f1dSLionel Sambuc case llvm::Triple::systemz:
7405*0a6a1f1dSLionel Sambuc return "elf64_s390";
7406*0a6a1f1dSLionel Sambuc case llvm::Triple::x86_64:
7407*0a6a1f1dSLionel Sambuc if (T.getEnvironment() == llvm::Triple::GNUX32)
7408*0a6a1f1dSLionel Sambuc return "elf32_x86_64";
7409*0a6a1f1dSLionel Sambuc return "elf_x86_64";
7410*0a6a1f1dSLionel Sambuc default:
7411*0a6a1f1dSLionel Sambuc llvm_unreachable("Unexpected arch");
7412*0a6a1f1dSLionel Sambuc }
7413*0a6a1f1dSLionel Sambuc }
7414*0a6a1f1dSLionel Sambuc
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const7415f4a2713aSLionel Sambuc void gnutools::Link::ConstructJob(Compilation &C, const JobAction &JA,
7416f4a2713aSLionel Sambuc const InputInfo &Output,
7417f4a2713aSLionel Sambuc const InputInfoList &Inputs,
7418f4a2713aSLionel Sambuc const ArgList &Args,
7419f4a2713aSLionel Sambuc const char *LinkingOutput) const {
7420f4a2713aSLionel Sambuc const toolchains::Linux& ToolChain =
7421f4a2713aSLionel Sambuc static_cast<const toolchains::Linux&>(getToolChain());
7422f4a2713aSLionel Sambuc const Driver &D = ToolChain.getDriver();
7423f4a2713aSLionel Sambuc const bool isAndroid =
7424f4a2713aSLionel Sambuc ToolChain.getTriple().getEnvironment() == llvm::Triple::Android;
7425f4a2713aSLionel Sambuc const bool IsPIE =
7426f4a2713aSLionel Sambuc !Args.hasArg(options::OPT_shared) &&
7427*0a6a1f1dSLionel Sambuc !Args.hasArg(options::OPT_static) &&
7428*0a6a1f1dSLionel Sambuc (Args.hasArg(options::OPT_pie) || ToolChain.isPIEDefault() ||
7429*0a6a1f1dSLionel Sambuc // On Android every code is PIC so every executable is PIE
7430*0a6a1f1dSLionel Sambuc // Cannot use isPIEDefault here since otherwise
7431*0a6a1f1dSLionel Sambuc // PIE only logic will be enabled during compilation
7432*0a6a1f1dSLionel Sambuc isAndroid);
7433f4a2713aSLionel Sambuc
7434f4a2713aSLionel Sambuc ArgStringList CmdArgs;
7435f4a2713aSLionel Sambuc
7436f4a2713aSLionel Sambuc // Silence warning for "clang -g foo.o -o foo"
7437f4a2713aSLionel Sambuc Args.ClaimAllArgs(options::OPT_g_Group);
7438f4a2713aSLionel Sambuc // and "clang -emit-llvm foo.o -o foo"
7439f4a2713aSLionel Sambuc Args.ClaimAllArgs(options::OPT_emit_llvm);
7440f4a2713aSLionel Sambuc // and for "clang -w foo.o -o foo". Other warning options are already
7441f4a2713aSLionel Sambuc // handled somewhere else.
7442f4a2713aSLionel Sambuc Args.ClaimAllArgs(options::OPT_w);
7443f4a2713aSLionel Sambuc
7444f4a2713aSLionel Sambuc if (!D.SysRoot.empty())
7445f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
7446f4a2713aSLionel Sambuc
7447f4a2713aSLionel Sambuc if (IsPIE)
7448f4a2713aSLionel Sambuc CmdArgs.push_back("-pie");
7449f4a2713aSLionel Sambuc
7450f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_rdynamic))
7451f4a2713aSLionel Sambuc CmdArgs.push_back("-export-dynamic");
7452f4a2713aSLionel Sambuc
7453f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_s))
7454f4a2713aSLionel Sambuc CmdArgs.push_back("-s");
7455f4a2713aSLionel Sambuc
7456*0a6a1f1dSLionel Sambuc if (ToolChain.getArch() == llvm::Triple::armeb ||
7457*0a6a1f1dSLionel Sambuc ToolChain.getArch() == llvm::Triple::thumbeb)
7458*0a6a1f1dSLionel Sambuc arm::appendEBLinkFlags(Args, CmdArgs, getToolChain().getTriple());
7459*0a6a1f1dSLionel Sambuc
7460*0a6a1f1dSLionel Sambuc for (const auto &Opt : ToolChain.ExtraOpts)
7461*0a6a1f1dSLionel Sambuc CmdArgs.push_back(Opt.c_str());
7462f4a2713aSLionel Sambuc
7463f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_static)) {
7464f4a2713aSLionel Sambuc CmdArgs.push_back("--eh-frame-hdr");
7465f4a2713aSLionel Sambuc }
7466f4a2713aSLionel Sambuc
7467f4a2713aSLionel Sambuc CmdArgs.push_back("-m");
7468*0a6a1f1dSLionel Sambuc CmdArgs.push_back(getLDMOption(ToolChain.getTriple(), Args));
7469f4a2713aSLionel Sambuc
7470f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_static)) {
7471*0a6a1f1dSLionel Sambuc if (ToolChain.getArch() == llvm::Triple::arm ||
7472*0a6a1f1dSLionel Sambuc ToolChain.getArch() == llvm::Triple::armeb ||
7473*0a6a1f1dSLionel Sambuc ToolChain.getArch() == llvm::Triple::thumb ||
7474*0a6a1f1dSLionel Sambuc ToolChain.getArch() == llvm::Triple::thumbeb)
7475f4a2713aSLionel Sambuc CmdArgs.push_back("-Bstatic");
7476f4a2713aSLionel Sambuc else
7477f4a2713aSLionel Sambuc CmdArgs.push_back("-static");
7478f4a2713aSLionel Sambuc } else if (Args.hasArg(options::OPT_shared)) {
7479f4a2713aSLionel Sambuc CmdArgs.push_back("-shared");
7480f4a2713aSLionel Sambuc }
7481f4a2713aSLionel Sambuc
7482f4a2713aSLionel Sambuc if (ToolChain.getArch() == llvm::Triple::arm ||
7483*0a6a1f1dSLionel Sambuc ToolChain.getArch() == llvm::Triple::armeb ||
7484f4a2713aSLionel Sambuc ToolChain.getArch() == llvm::Triple::thumb ||
7485*0a6a1f1dSLionel Sambuc ToolChain.getArch() == llvm::Triple::thumbeb ||
7486f4a2713aSLionel Sambuc (!Args.hasArg(options::OPT_static) &&
7487f4a2713aSLionel Sambuc !Args.hasArg(options::OPT_shared))) {
7488f4a2713aSLionel Sambuc CmdArgs.push_back("-dynamic-linker");
7489f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(
7490f4a2713aSLionel Sambuc D.DyldPrefix + getLinuxDynamicLinker(Args, ToolChain)));
7491f4a2713aSLionel Sambuc }
7492f4a2713aSLionel Sambuc
7493f4a2713aSLionel Sambuc CmdArgs.push_back("-o");
7494f4a2713aSLionel Sambuc CmdArgs.push_back(Output.getFilename());
7495f4a2713aSLionel Sambuc
7496f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_nostdlib) &&
7497f4a2713aSLionel Sambuc !Args.hasArg(options::OPT_nostartfiles)) {
7498f4a2713aSLionel Sambuc if (!isAndroid) {
7499*0a6a1f1dSLionel Sambuc const char *crt1 = nullptr;
7500f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_shared)){
7501f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_pg))
7502f4a2713aSLionel Sambuc crt1 = "gcrt1.o";
7503f4a2713aSLionel Sambuc else if (IsPIE)
7504f4a2713aSLionel Sambuc crt1 = "Scrt1.o";
7505f4a2713aSLionel Sambuc else
7506f4a2713aSLionel Sambuc crt1 = "crt1.o";
7507f4a2713aSLionel Sambuc }
7508f4a2713aSLionel Sambuc if (crt1)
7509f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crt1)));
7510f4a2713aSLionel Sambuc
7511f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o")));
7512f4a2713aSLionel Sambuc }
7513f4a2713aSLionel Sambuc
7514f4a2713aSLionel Sambuc const char *crtbegin;
7515f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_static))
7516f4a2713aSLionel Sambuc crtbegin = isAndroid ? "crtbegin_static.o" : "crtbeginT.o";
7517f4a2713aSLionel Sambuc else if (Args.hasArg(options::OPT_shared))
7518f4a2713aSLionel Sambuc crtbegin = isAndroid ? "crtbegin_so.o" : "crtbeginS.o";
7519f4a2713aSLionel Sambuc else if (IsPIE)
7520f4a2713aSLionel Sambuc crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbeginS.o";
7521f4a2713aSLionel Sambuc else
7522f4a2713aSLionel Sambuc crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbegin.o";
7523f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin)));
7524f4a2713aSLionel Sambuc
7525f4a2713aSLionel Sambuc // Add crtfastmath.o if available and fast math is enabled.
7526f4a2713aSLionel Sambuc ToolChain.AddFastMathRuntimeIfAvailable(Args, CmdArgs);
7527f4a2713aSLionel Sambuc }
7528f4a2713aSLionel Sambuc
7529f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_L);
7530*0a6a1f1dSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_u);
7531f4a2713aSLionel Sambuc
7532*0a6a1f1dSLionel Sambuc const ToolChain::path_list &Paths = ToolChain.getFilePaths();
7533f4a2713aSLionel Sambuc
7534*0a6a1f1dSLionel Sambuc for (const auto &Path : Paths)
7535*0a6a1f1dSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + Path));
7536f4a2713aSLionel Sambuc
7537*0a6a1f1dSLionel Sambuc if (D.IsUsingLTO(Args))
7538*0a6a1f1dSLionel Sambuc AddGoldPlugin(ToolChain, Args, CmdArgs);
7539f4a2713aSLionel Sambuc
7540f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
7541f4a2713aSLionel Sambuc CmdArgs.push_back("--no-demangle");
7542f4a2713aSLionel Sambuc
7543*0a6a1f1dSLionel Sambuc bool NeedsSanitizerDeps = addSanitizerRuntimes(ToolChain, Args, CmdArgs);
7544f4a2713aSLionel Sambuc AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
7545f4a2713aSLionel Sambuc // The profile runtime also needs access to system libraries.
7546*0a6a1f1dSLionel Sambuc addProfileRT(getToolChain(), Args, CmdArgs);
7547f4a2713aSLionel Sambuc
7548f4a2713aSLionel Sambuc if (D.CCCIsCXX() &&
7549f4a2713aSLionel Sambuc !Args.hasArg(options::OPT_nostdlib) &&
7550f4a2713aSLionel Sambuc !Args.hasArg(options::OPT_nodefaultlibs)) {
7551f4a2713aSLionel Sambuc bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
7552f4a2713aSLionel Sambuc !Args.hasArg(options::OPT_static);
7553f4a2713aSLionel Sambuc if (OnlyLibstdcxxStatic)
7554f4a2713aSLionel Sambuc CmdArgs.push_back("-Bstatic");
7555f4a2713aSLionel Sambuc ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
7556f4a2713aSLionel Sambuc if (OnlyLibstdcxxStatic)
7557f4a2713aSLionel Sambuc CmdArgs.push_back("-Bdynamic");
7558f4a2713aSLionel Sambuc CmdArgs.push_back("-lm");
7559f4a2713aSLionel Sambuc }
7560f4a2713aSLionel Sambuc
7561f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_nostdlib)) {
7562f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_nodefaultlibs)) {
7563f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_static))
7564f4a2713aSLionel Sambuc CmdArgs.push_back("--start-group");
7565f4a2713aSLionel Sambuc
7566*0a6a1f1dSLionel Sambuc if (NeedsSanitizerDeps)
7567*0a6a1f1dSLionel Sambuc linkSanitizerRuntimeDeps(ToolChain, CmdArgs);
7568*0a6a1f1dSLionel Sambuc
7569*0a6a1f1dSLionel Sambuc LibOpenMP UsedOpenMPLib = LibUnknown;
7570*0a6a1f1dSLionel Sambuc if (Args.hasArg(options::OPT_fopenmp)) {
7571*0a6a1f1dSLionel Sambuc UsedOpenMPLib = LibGOMP;
7572*0a6a1f1dSLionel Sambuc } else if (const Arg *A = Args.getLastArg(options::OPT_fopenmp_EQ)) {
7573*0a6a1f1dSLionel Sambuc UsedOpenMPLib = llvm::StringSwitch<LibOpenMP>(A->getValue())
7574*0a6a1f1dSLionel Sambuc .Case("libgomp", LibGOMP)
7575*0a6a1f1dSLionel Sambuc .Case("libiomp5", LibIOMP5)
7576*0a6a1f1dSLionel Sambuc .Default(LibUnknown);
7577*0a6a1f1dSLionel Sambuc if (UsedOpenMPLib == LibUnknown)
7578*0a6a1f1dSLionel Sambuc D.Diag(diag::err_drv_unsupported_option_argument)
7579*0a6a1f1dSLionel Sambuc << A->getOption().getName() << A->getValue();
7580*0a6a1f1dSLionel Sambuc }
7581*0a6a1f1dSLionel Sambuc switch (UsedOpenMPLib) {
7582*0a6a1f1dSLionel Sambuc case LibGOMP:
7583f4a2713aSLionel Sambuc CmdArgs.push_back("-lgomp");
7584f4a2713aSLionel Sambuc
7585*0a6a1f1dSLionel Sambuc // FIXME: Exclude this for platforms with libgomp that don't require
7586*0a6a1f1dSLionel Sambuc // librt. Most modern Linux platforms require it, but some may not.
7587f4a2713aSLionel Sambuc CmdArgs.push_back("-lrt");
7588*0a6a1f1dSLionel Sambuc break;
7589*0a6a1f1dSLionel Sambuc case LibIOMP5:
7590*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-liomp5");
7591*0a6a1f1dSLionel Sambuc break;
7592*0a6a1f1dSLionel Sambuc case LibUnknown:
7593*0a6a1f1dSLionel Sambuc break;
7594f4a2713aSLionel Sambuc }
7595*0a6a1f1dSLionel Sambuc AddRunTimeLibs(ToolChain, D, CmdArgs, Args);
7596f4a2713aSLionel Sambuc
7597*0a6a1f1dSLionel Sambuc if ((Args.hasArg(options::OPT_pthread) ||
7598*0a6a1f1dSLionel Sambuc Args.hasArg(options::OPT_pthreads) || UsedOpenMPLib != LibUnknown) &&
7599*0a6a1f1dSLionel Sambuc !isAndroid)
7600f4a2713aSLionel Sambuc CmdArgs.push_back("-lpthread");
7601f4a2713aSLionel Sambuc
7602f4a2713aSLionel Sambuc CmdArgs.push_back("-lc");
7603f4a2713aSLionel Sambuc
7604f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_static))
7605f4a2713aSLionel Sambuc CmdArgs.push_back("--end-group");
7606f4a2713aSLionel Sambuc else
7607*0a6a1f1dSLionel Sambuc AddRunTimeLibs(ToolChain, D, CmdArgs, Args);
7608f4a2713aSLionel Sambuc }
7609f4a2713aSLionel Sambuc
7610f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_nostartfiles)) {
7611f4a2713aSLionel Sambuc const char *crtend;
7612f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_shared))
7613f4a2713aSLionel Sambuc crtend = isAndroid ? "crtend_so.o" : "crtendS.o";
7614f4a2713aSLionel Sambuc else if (IsPIE)
7615f4a2713aSLionel Sambuc crtend = isAndroid ? "crtend_android.o" : "crtendS.o";
7616f4a2713aSLionel Sambuc else
7617f4a2713aSLionel Sambuc crtend = isAndroid ? "crtend_android.o" : "crtend.o";
7618f4a2713aSLionel Sambuc
7619f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtend)));
7620f4a2713aSLionel Sambuc if (!isAndroid)
7621f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o")));
7622f4a2713aSLionel Sambuc }
7623f4a2713aSLionel Sambuc }
7624f4a2713aSLionel Sambuc
7625*0a6a1f1dSLionel Sambuc C.addCommand(
7626*0a6a1f1dSLionel Sambuc llvm::make_unique<Command>(JA, *this, ToolChain.Linker.c_str(), CmdArgs));
7627f4a2713aSLionel Sambuc }
7628f4a2713aSLionel Sambuc
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const7629f4a2713aSLionel Sambuc void minix::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
7630f4a2713aSLionel Sambuc const InputInfo &Output,
7631f4a2713aSLionel Sambuc const InputInfoList &Inputs,
7632f4a2713aSLionel Sambuc const ArgList &Args,
7633f4a2713aSLionel Sambuc const char *LinkingOutput) const {
7634*0a6a1f1dSLionel Sambuc claimNoWarnArgs(Args);
7635f4a2713aSLionel Sambuc ArgStringList CmdArgs;
7636f4a2713aSLionel Sambuc
7637*0a6a1f1dSLionel Sambuc // GNU as needs different flags for creating the correct output format
7638*0a6a1f1dSLionel Sambuc // on architectures with different ABIs or optional feature sets.
7639*0a6a1f1dSLionel Sambuc switch (getToolChain().getArch()) {
7640*0a6a1f1dSLionel Sambuc case llvm::Triple::x86:
76414684ddb6SLionel Sambuc CmdArgs.push_back("--32");
7642*0a6a1f1dSLionel Sambuc break;
7643*0a6a1f1dSLionel Sambuc case llvm::Triple::arm:
7644*0a6a1f1dSLionel Sambuc case llvm::Triple::armeb:
7645*0a6a1f1dSLionel Sambuc case llvm::Triple::thumb:
7646*0a6a1f1dSLionel Sambuc case llvm::Triple::thumbeb: {
7647*0a6a1f1dSLionel Sambuc std::string MArch(arm::getARMTargetCPU(Args, getToolChain().getTriple()));
7648*0a6a1f1dSLionel Sambuc CmdArgs.push_back(Args.MakeArgString("-mcpu=" + MArch));
7649*0a6a1f1dSLionel Sambuc break;
7650*0a6a1f1dSLionel Sambuc }
76514684ddb6SLionel Sambuc
7652*0a6a1f1dSLionel Sambuc #if 0 /* LSC: Not needed for MINIX but kept to ease comparison with NetBSD. */
7653*0a6a1f1dSLionel Sambuc case llvm::Triple::mips:
7654*0a6a1f1dSLionel Sambuc case llvm::Triple::mipsel:
7655*0a6a1f1dSLionel Sambuc case llvm::Triple::mips64:
7656*0a6a1f1dSLionel Sambuc case llvm::Triple::mips64el: {
7657*0a6a1f1dSLionel Sambuc StringRef CPUName;
7658*0a6a1f1dSLionel Sambuc StringRef ABIName;
7659*0a6a1f1dSLionel Sambuc mips::getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName);
7660*0a6a1f1dSLionel Sambuc
7661*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-march");
7662*0a6a1f1dSLionel Sambuc CmdArgs.push_back(CPUName.data());
7663*0a6a1f1dSLionel Sambuc
7664*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-mabi");
7665*0a6a1f1dSLionel Sambuc CmdArgs.push_back(getGnuCompatibleMipsABIName(ABIName).data());
7666*0a6a1f1dSLionel Sambuc
7667*0a6a1f1dSLionel Sambuc if (getToolChain().getArch() == llvm::Triple::mips ||
7668*0a6a1f1dSLionel Sambuc getToolChain().getArch() == llvm::Triple::mips64)
76694684ddb6SLionel Sambuc CmdArgs.push_back("-EB");
7670*0a6a1f1dSLionel Sambuc else
76714684ddb6SLionel Sambuc CmdArgs.push_back("-EL");
7672*0a6a1f1dSLionel Sambuc
7673*0a6a1f1dSLionel Sambuc addAssemblerKPIC(Args, CmdArgs);
7674*0a6a1f1dSLionel Sambuc break;
7675*0a6a1f1dSLionel Sambuc }
7676*0a6a1f1dSLionel Sambuc
7677*0a6a1f1dSLionel Sambuc case llvm::Triple::sparc:
7678*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-32");
7679*0a6a1f1dSLionel Sambuc addAssemblerKPIC(Args, CmdArgs);
7680*0a6a1f1dSLionel Sambuc break;
7681*0a6a1f1dSLionel Sambuc
7682*0a6a1f1dSLionel Sambuc case llvm::Triple::sparcv9:
7683*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-64");
7684*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-Av9");
7685*0a6a1f1dSLionel Sambuc addAssemblerKPIC(Args, CmdArgs);
7686*0a6a1f1dSLionel Sambuc break;
76874684ddb6SLionel Sambuc #endif /* 0 */
76884684ddb6SLionel Sambuc
7689*0a6a1f1dSLionel Sambuc default:
7690*0a6a1f1dSLionel Sambuc break;
7691*0a6a1f1dSLionel Sambuc }
7692*0a6a1f1dSLionel Sambuc
7693f4a2713aSLionel Sambuc Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
7694f4a2713aSLionel Sambuc options::OPT_Xassembler);
7695f4a2713aSLionel Sambuc
7696f4a2713aSLionel Sambuc CmdArgs.push_back("-o");
7697f4a2713aSLionel Sambuc CmdArgs.push_back(Output.getFilename());
7698f4a2713aSLionel Sambuc
7699*0a6a1f1dSLionel Sambuc for (const auto &II : Inputs)
7700f4a2713aSLionel Sambuc CmdArgs.push_back(II.getFilename());
7701f4a2713aSLionel Sambuc
77024684ddb6SLionel Sambuc const char *Exec = Args.MakeArgString((getToolChain().GetProgramPath("as")));
7703*0a6a1f1dSLionel Sambuc C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
7704f4a2713aSLionel Sambuc }
7705f4a2713aSLionel Sambuc
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const7706f4a2713aSLionel Sambuc void minix::Link::ConstructJob(Compilation &C, const JobAction &JA,
7707f4a2713aSLionel Sambuc const InputInfo &Output,
7708f4a2713aSLionel Sambuc const InputInfoList &Inputs,
7709f4a2713aSLionel Sambuc const ArgList &Args,
7710f4a2713aSLionel Sambuc const char *LinkingOutput) const {
7711f4a2713aSLionel Sambuc const Driver &D = getToolChain().getDriver();
7712f4a2713aSLionel Sambuc ArgStringList CmdArgs;
7713f4a2713aSLionel Sambuc
77144684ddb6SLionel Sambuc if (!D.SysRoot.empty())
77154684ddb6SLionel Sambuc CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
77164684ddb6SLionel Sambuc
7717*0a6a1f1dSLionel Sambuc CmdArgs.push_back("--eh-frame-hdr");
77184684ddb6SLionel Sambuc if (Args.hasArg(options::OPT_static)) {
77194684ddb6SLionel Sambuc CmdArgs.push_back("-Bstatic");
77204684ddb6SLionel Sambuc } else {
77214684ddb6SLionel Sambuc if (Args.hasArg(options::OPT_rdynamic))
77224684ddb6SLionel Sambuc CmdArgs.push_back("-export-dynamic");
77234684ddb6SLionel Sambuc if (Args.hasArg(options::OPT_shared)) {
77244684ddb6SLionel Sambuc CmdArgs.push_back("-Bshareable");
77254684ddb6SLionel Sambuc } else {
77264684ddb6SLionel Sambuc CmdArgs.push_back("-dynamic-linker");
77274684ddb6SLionel Sambuc // LSC: Small deviation from the NetBSD version.
77284684ddb6SLionel Sambuc // Use the same linker path as gcc.
77294684ddb6SLionel Sambuc CmdArgs.push_back("/usr/libexec/ld.elf_so");
77304684ddb6SLionel Sambuc }
77314684ddb6SLionel Sambuc }
77324684ddb6SLionel Sambuc
7733*0a6a1f1dSLionel Sambuc // Many NetBSD architectures support more than one ABI.
7734*0a6a1f1dSLionel Sambuc // Determine the correct emulation for ld.
7735*0a6a1f1dSLionel Sambuc switch (getToolChain().getArch()) {
7736*0a6a1f1dSLionel Sambuc case llvm::Triple::x86:
77374684ddb6SLionel Sambuc CmdArgs.push_back("-m");
77384684ddb6SLionel Sambuc CmdArgs.push_back("elf_i386_minix");
7739*0a6a1f1dSLionel Sambuc #if 0 /* LSC: Not needed for MINIX but kept to ease comparison with NetBSD. */
7740*0a6a1f1dSLionel Sambuc CmdArgs.push_back("elf_i386");
7741*0a6a1f1dSLionel Sambuc break;
7742*0a6a1f1dSLionel Sambuc case llvm::Triple::arm:
7743*0a6a1f1dSLionel Sambuc case llvm::Triple::thumb:
7744*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-m");
7745*0a6a1f1dSLionel Sambuc switch (getToolChain().getTriple().getEnvironment()) {
7746*0a6a1f1dSLionel Sambuc case llvm::Triple::EABI:
7747*0a6a1f1dSLionel Sambuc case llvm::Triple::GNUEABI:
7748*0a6a1f1dSLionel Sambuc CmdArgs.push_back("armelf_nbsd_eabi");
7749*0a6a1f1dSLionel Sambuc break;
7750*0a6a1f1dSLionel Sambuc case llvm::Triple::EABIHF:
7751*0a6a1f1dSLionel Sambuc case llvm::Triple::GNUEABIHF:
7752*0a6a1f1dSLionel Sambuc CmdArgs.push_back("armelf_nbsd_eabihf");
7753*0a6a1f1dSLionel Sambuc break;
7754*0a6a1f1dSLionel Sambuc default:
7755*0a6a1f1dSLionel Sambuc CmdArgs.push_back("armelf_nbsd");
7756*0a6a1f1dSLionel Sambuc break;
7757*0a6a1f1dSLionel Sambuc }
7758*0a6a1f1dSLionel Sambuc break;
7759*0a6a1f1dSLionel Sambuc case llvm::Triple::armeb:
7760*0a6a1f1dSLionel Sambuc case llvm::Triple::thumbeb:
7761*0a6a1f1dSLionel Sambuc arm::appendEBLinkFlags(Args, CmdArgs, getToolChain().getTriple());
7762*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-m");
7763*0a6a1f1dSLionel Sambuc switch (getToolChain().getTriple().getEnvironment()) {
7764*0a6a1f1dSLionel Sambuc case llvm::Triple::EABI:
7765*0a6a1f1dSLionel Sambuc case llvm::Triple::GNUEABI:
7766*0a6a1f1dSLionel Sambuc CmdArgs.push_back("armelfb_nbsd_eabi");
7767*0a6a1f1dSLionel Sambuc break;
7768*0a6a1f1dSLionel Sambuc case llvm::Triple::EABIHF:
7769*0a6a1f1dSLionel Sambuc case llvm::Triple::GNUEABIHF:
7770*0a6a1f1dSLionel Sambuc CmdArgs.push_back("armelfb_nbsd_eabihf");
7771*0a6a1f1dSLionel Sambuc break;
7772*0a6a1f1dSLionel Sambuc default:
7773*0a6a1f1dSLionel Sambuc CmdArgs.push_back("armelfb_nbsd");
7774*0a6a1f1dSLionel Sambuc break;
7775*0a6a1f1dSLionel Sambuc }
7776*0a6a1f1dSLionel Sambuc break;
7777*0a6a1f1dSLionel Sambuc case llvm::Triple::mips64:
7778*0a6a1f1dSLionel Sambuc case llvm::Triple::mips64el:
7779*0a6a1f1dSLionel Sambuc if (mips::hasMipsAbiArg(Args, "32")) {
7780*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-m");
7781*0a6a1f1dSLionel Sambuc if (getToolChain().getArch() == llvm::Triple::mips64)
7782*0a6a1f1dSLionel Sambuc CmdArgs.push_back("elf32btsmip");
7783*0a6a1f1dSLionel Sambuc else
7784*0a6a1f1dSLionel Sambuc CmdArgs.push_back("elf32ltsmip");
7785*0a6a1f1dSLionel Sambuc } else if (mips::hasMipsAbiArg(Args, "64")) {
7786*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-m");
7787*0a6a1f1dSLionel Sambuc if (getToolChain().getArch() == llvm::Triple::mips64)
7788*0a6a1f1dSLionel Sambuc CmdArgs.push_back("elf64btsmip");
7789*0a6a1f1dSLionel Sambuc else
7790*0a6a1f1dSLionel Sambuc CmdArgs.push_back("elf64ltsmip");
7791*0a6a1f1dSLionel Sambuc }
7792*0a6a1f1dSLionel Sambuc break;
7793*0a6a1f1dSLionel Sambuc case llvm::Triple::ppc:
7794*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-m");
7795*0a6a1f1dSLionel Sambuc CmdArgs.push_back("elf32ppc_nbsd");
7796*0a6a1f1dSLionel Sambuc break;
7797*0a6a1f1dSLionel Sambuc
7798*0a6a1f1dSLionel Sambuc case llvm::Triple::ppc64:
7799*0a6a1f1dSLionel Sambuc case llvm::Triple::ppc64le:
7800*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-m");
7801*0a6a1f1dSLionel Sambuc CmdArgs.push_back("elf64ppc");
7802*0a6a1f1dSLionel Sambuc break;
7803*0a6a1f1dSLionel Sambuc
7804*0a6a1f1dSLionel Sambuc case llvm::Triple::sparc:
7805*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-m");
7806*0a6a1f1dSLionel Sambuc CmdArgs.push_back("elf32_sparc");
7807*0a6a1f1dSLionel Sambuc break;
7808*0a6a1f1dSLionel Sambuc
7809*0a6a1f1dSLionel Sambuc case llvm::Triple::sparcv9:
7810*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-m");
7811*0a6a1f1dSLionel Sambuc CmdArgs.push_back("elf64_sparc");
7812*0a6a1f1dSLionel Sambuc break;
7813*0a6a1f1dSLionel Sambuc #endif /* 0 */
7814*0a6a1f1dSLionel Sambuc
7815*0a6a1f1dSLionel Sambuc default:
7816*0a6a1f1dSLionel Sambuc break;
78174684ddb6SLionel Sambuc }
78184684ddb6SLionel Sambuc
7819f4a2713aSLionel Sambuc if (Output.isFilename()) {
7820f4a2713aSLionel Sambuc CmdArgs.push_back("-o");
7821f4a2713aSLionel Sambuc CmdArgs.push_back(Output.getFilename());
7822f4a2713aSLionel Sambuc } else {
7823f4a2713aSLionel Sambuc assert(Output.isNothing() && "Invalid output.");
7824f4a2713aSLionel Sambuc }
7825f4a2713aSLionel Sambuc
7826f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_nostdlib) &&
7827f4a2713aSLionel Sambuc !Args.hasArg(options::OPT_nostartfiles)) {
78284684ddb6SLionel Sambuc if (!Args.hasArg(options::OPT_shared)) {
78294684ddb6SLionel Sambuc CmdArgs.push_back(Args.MakeArgString(
78304684ddb6SLionel Sambuc getToolChain().GetFilePath("crt0.o")));
78314684ddb6SLionel Sambuc CmdArgs.push_back(Args.MakeArgString(
78324684ddb6SLionel Sambuc getToolChain().GetFilePath("crti.o")));
78334684ddb6SLionel Sambuc CmdArgs.push_back(Args.MakeArgString(
78344684ddb6SLionel Sambuc getToolChain().GetFilePath("crtbegin.o")));
78354684ddb6SLionel Sambuc } else {
78364684ddb6SLionel Sambuc CmdArgs.push_back(Args.MakeArgString(
78374684ddb6SLionel Sambuc getToolChain().GetFilePath("crti.o")));
78384684ddb6SLionel Sambuc CmdArgs.push_back(Args.MakeArgString(
78394684ddb6SLionel Sambuc getToolChain().GetFilePath("crtbeginS.o")));
78404684ddb6SLionel Sambuc }
7841f4a2713aSLionel Sambuc }
7842f4a2713aSLionel Sambuc
7843f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_L);
7844f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
7845f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_e);
78464684ddb6SLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_s);
78474684ddb6SLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_t);
78484684ddb6SLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag);
78494684ddb6SLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_r);
7850f4a2713aSLionel Sambuc
7851f4a2713aSLionel Sambuc AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
7852f4a2713aSLionel Sambuc
78534684ddb6SLionel Sambuc #if 0 /* LSC: Not needed for MINIX, but kept to ease comparison with NetBSD. */
78544684ddb6SLionel Sambuc unsigned Major, Minor, Micro;
78554684ddb6SLionel Sambuc getToolChain().getTriple().getOSVersion(Major, Minor, Micro);
78564684ddb6SLionel Sambuc bool useLibgcc = true;
7857*0a6a1f1dSLionel Sambuc if (Major >= 7 || (Major == 6 && Minor == 99 && Micro >= 49) || Major == 0) {
7858*0a6a1f1dSLionel Sambuc switch(getToolChain().getArch()) {
7859*0a6a1f1dSLionel Sambuc case llvm::Triple::aarch64:
7860*0a6a1f1dSLionel Sambuc case llvm::Triple::arm:
7861*0a6a1f1dSLionel Sambuc case llvm::Triple::armeb:
7862*0a6a1f1dSLionel Sambuc case llvm::Triple::thumb:
7863*0a6a1f1dSLionel Sambuc case llvm::Triple::thumbeb:
7864*0a6a1f1dSLionel Sambuc case llvm::Triple::ppc:
7865*0a6a1f1dSLionel Sambuc case llvm::Triple::ppc64:
7866*0a6a1f1dSLionel Sambuc case llvm::Triple::ppc64le:
7867*0a6a1f1dSLionel Sambuc case llvm::Triple::x86:
7868*0a6a1f1dSLionel Sambuc case llvm::Triple::x86_64:
78694684ddb6SLionel Sambuc useLibgcc = false;
7870*0a6a1f1dSLionel Sambuc break;
7871*0a6a1f1dSLionel Sambuc default:
7872*0a6a1f1dSLionel Sambuc break;
7873*0a6a1f1dSLionel Sambuc }
78744684ddb6SLionel Sambuc }
78754684ddb6SLionel Sambuc #endif /* 0 */
7876f4a2713aSLionel Sambuc
7877f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_nostdlib) &&
7878f4a2713aSLionel Sambuc !Args.hasArg(options::OPT_nodefaultlibs)) {
7879f4a2713aSLionel Sambuc if (D.CCCIsCXX()) {
7880f4a2713aSLionel Sambuc getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
7881f4a2713aSLionel Sambuc CmdArgs.push_back("-lm");
78824684ddb6SLionel Sambuc
78834684ddb6SLionel Sambuc /* LSC: Hack as lc++ is linked against mthread. */
78844684ddb6SLionel Sambuc CmdArgs.push_back("-lmthread");
7885f4a2713aSLionel Sambuc }
78864684ddb6SLionel Sambuc if (Args.hasArg(options::OPT_pthread))
78874684ddb6SLionel Sambuc CmdArgs.push_back("-lpthread");
78884684ddb6SLionel Sambuc CmdArgs.push_back("-lc");
78894684ddb6SLionel Sambuc
78904684ddb6SLionel Sambuc #if 0 /* LSC: Minix always use CompilerRT-Generic. */
78914684ddb6SLionel Sambuc if (useLibgcc) {
78924684ddb6SLionel Sambuc if (Args.hasArg(options::OPT_static)) {
78934684ddb6SLionel Sambuc // libgcc_eh depends on libc, so resolve as much as possible,
78944684ddb6SLionel Sambuc // pull in any new requirements from libc and then get the rest
78954684ddb6SLionel Sambuc // of libgcc.
78964684ddb6SLionel Sambuc CmdArgs.push_back("-lgcc_eh");
78974684ddb6SLionel Sambuc CmdArgs.push_back("-lc");
78984684ddb6SLionel Sambuc CmdArgs.push_back("-lgcc");
78994684ddb6SLionel Sambuc } else {
79004684ddb6SLionel Sambuc CmdArgs.push_back("-lgcc");
79014684ddb6SLionel Sambuc CmdArgs.push_back("--as-needed");
79024684ddb6SLionel Sambuc CmdArgs.push_back("-lgcc_s");
79034684ddb6SLionel Sambuc CmdArgs.push_back("--no-as-needed");
79044684ddb6SLionel Sambuc }
79054684ddb6SLionel Sambuc }
79064684ddb6SLionel Sambuc #endif /* 0 */
7907f4a2713aSLionel Sambuc }
7908f4a2713aSLionel Sambuc
7909f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_nostdlib) &&
7910f4a2713aSLionel Sambuc !Args.hasArg(options::OPT_nostartfiles)) {
79114684ddb6SLionel Sambuc if (!Args.hasArg(options::OPT_shared))
79124684ddb6SLionel Sambuc CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(
79134684ddb6SLionel Sambuc "crtend.o")));
79144684ddb6SLionel Sambuc else
79154684ddb6SLionel Sambuc CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(
79164684ddb6SLionel Sambuc "crtendS.o")));
79174684ddb6SLionel Sambuc CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(
79184684ddb6SLionel Sambuc "crtn.o")));
7919f4a2713aSLionel Sambuc }
7920f4a2713aSLionel Sambuc
7921*0a6a1f1dSLionel Sambuc addProfileRT(getToolChain(), Args, CmdArgs);
79224684ddb6SLionel Sambuc
7923*0a6a1f1dSLionel Sambuc const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
7924*0a6a1f1dSLionel Sambuc C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
7925f4a2713aSLionel Sambuc }
7926f4a2713aSLionel Sambuc
7927f4a2713aSLionel Sambuc /// DragonFly Tools
7928f4a2713aSLionel Sambuc
7929f4a2713aSLionel Sambuc // For now, DragonFly Assemble does just about the same as for
7930f4a2713aSLionel Sambuc // FreeBSD, but this may change soon.
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const7931f4a2713aSLionel Sambuc void dragonfly::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
7932f4a2713aSLionel Sambuc const InputInfo &Output,
7933f4a2713aSLionel Sambuc const InputInfoList &Inputs,
7934f4a2713aSLionel Sambuc const ArgList &Args,
7935f4a2713aSLionel Sambuc const char *LinkingOutput) const {
7936*0a6a1f1dSLionel Sambuc claimNoWarnArgs(Args);
7937f4a2713aSLionel Sambuc ArgStringList CmdArgs;
7938f4a2713aSLionel Sambuc
7939f4a2713aSLionel Sambuc // When building 32-bit code on DragonFly/pc64, we have to explicitly
7940f4a2713aSLionel Sambuc // instruct as in the base system to assemble 32-bit code.
7941f4a2713aSLionel Sambuc if (getToolChain().getArch() == llvm::Triple::x86)
7942f4a2713aSLionel Sambuc CmdArgs.push_back("--32");
7943f4a2713aSLionel Sambuc
7944*0a6a1f1dSLionel Sambuc Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
7945f4a2713aSLionel Sambuc
7946f4a2713aSLionel Sambuc CmdArgs.push_back("-o");
7947f4a2713aSLionel Sambuc CmdArgs.push_back(Output.getFilename());
7948f4a2713aSLionel Sambuc
7949*0a6a1f1dSLionel Sambuc for (const auto &II : Inputs)
7950f4a2713aSLionel Sambuc CmdArgs.push_back(II.getFilename());
7951f4a2713aSLionel Sambuc
7952*0a6a1f1dSLionel Sambuc const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
7953*0a6a1f1dSLionel Sambuc C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
7954f4a2713aSLionel Sambuc }
7955f4a2713aSLionel Sambuc
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const7956f4a2713aSLionel Sambuc void dragonfly::Link::ConstructJob(Compilation &C, const JobAction &JA,
7957f4a2713aSLionel Sambuc const InputInfo &Output,
7958f4a2713aSLionel Sambuc const InputInfoList &Inputs,
7959f4a2713aSLionel Sambuc const ArgList &Args,
7960f4a2713aSLionel Sambuc const char *LinkingOutput) const {
7961f4a2713aSLionel Sambuc const Driver &D = getToolChain().getDriver();
7962f4a2713aSLionel Sambuc ArgStringList CmdArgs;
7963*0a6a1f1dSLionel Sambuc bool UseGCC47 = llvm::sys::fs::exists("/usr/lib/gcc47");
7964f4a2713aSLionel Sambuc
7965f4a2713aSLionel Sambuc if (!D.SysRoot.empty())
7966f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
7967f4a2713aSLionel Sambuc
7968f4a2713aSLionel Sambuc CmdArgs.push_back("--eh-frame-hdr");
7969f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_static)) {
7970f4a2713aSLionel Sambuc CmdArgs.push_back("-Bstatic");
7971f4a2713aSLionel Sambuc } else {
7972f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_rdynamic))
7973f4a2713aSLionel Sambuc CmdArgs.push_back("-export-dynamic");
7974f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_shared))
7975f4a2713aSLionel Sambuc CmdArgs.push_back("-Bshareable");
7976f4a2713aSLionel Sambuc else {
7977f4a2713aSLionel Sambuc CmdArgs.push_back("-dynamic-linker");
7978f4a2713aSLionel Sambuc CmdArgs.push_back("/usr/libexec/ld-elf.so.2");
7979f4a2713aSLionel Sambuc }
7980f4a2713aSLionel Sambuc CmdArgs.push_back("--hash-style=both");
7981f4a2713aSLionel Sambuc }
7982f4a2713aSLionel Sambuc
7983f4a2713aSLionel Sambuc // When building 32-bit code on DragonFly/pc64, we have to explicitly
7984f4a2713aSLionel Sambuc // instruct ld in the base system to link 32-bit code.
7985f4a2713aSLionel Sambuc if (getToolChain().getArch() == llvm::Triple::x86) {
7986f4a2713aSLionel Sambuc CmdArgs.push_back("-m");
7987f4a2713aSLionel Sambuc CmdArgs.push_back("elf_i386");
7988f4a2713aSLionel Sambuc }
7989f4a2713aSLionel Sambuc
7990f4a2713aSLionel Sambuc if (Output.isFilename()) {
7991f4a2713aSLionel Sambuc CmdArgs.push_back("-o");
7992f4a2713aSLionel Sambuc CmdArgs.push_back(Output.getFilename());
7993f4a2713aSLionel Sambuc } else {
7994f4a2713aSLionel Sambuc assert(Output.isNothing() && "Invalid output.");
7995f4a2713aSLionel Sambuc }
7996f4a2713aSLionel Sambuc
7997f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_nostdlib) &&
7998f4a2713aSLionel Sambuc !Args.hasArg(options::OPT_nostartfiles)) {
7999f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_shared)) {
8000f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_pg))
8001f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(
8002f4a2713aSLionel Sambuc getToolChain().GetFilePath("gcrt1.o")));
8003f4a2713aSLionel Sambuc else {
8004f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_pie))
8005f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(
8006f4a2713aSLionel Sambuc getToolChain().GetFilePath("Scrt1.o")));
8007f4a2713aSLionel Sambuc else
8008f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(
8009f4a2713aSLionel Sambuc getToolChain().GetFilePath("crt1.o")));
8010f4a2713aSLionel Sambuc }
8011f4a2713aSLionel Sambuc }
8012f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(
8013f4a2713aSLionel Sambuc getToolChain().GetFilePath("crti.o")));
8014f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
8015f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(
8016f4a2713aSLionel Sambuc getToolChain().GetFilePath("crtbeginS.o")));
8017f4a2713aSLionel Sambuc else
8018f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(
8019f4a2713aSLionel Sambuc getToolChain().GetFilePath("crtbegin.o")));
8020f4a2713aSLionel Sambuc }
8021f4a2713aSLionel Sambuc
8022f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_L);
8023f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
8024f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_e);
8025f4a2713aSLionel Sambuc
8026f4a2713aSLionel Sambuc AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
8027f4a2713aSLionel Sambuc
8028f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_nostdlib) &&
8029f4a2713aSLionel Sambuc !Args.hasArg(options::OPT_nodefaultlibs)) {
8030f4a2713aSLionel Sambuc // FIXME: GCC passes on -lgcc, -lgcc_pic and a whole lot of
8031f4a2713aSLionel Sambuc // rpaths
8032f4a2713aSLionel Sambuc if (UseGCC47)
8033f4a2713aSLionel Sambuc CmdArgs.push_back("-L/usr/lib/gcc47");
8034f4a2713aSLionel Sambuc else
8035f4a2713aSLionel Sambuc CmdArgs.push_back("-L/usr/lib/gcc44");
8036f4a2713aSLionel Sambuc
8037f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_static)) {
8038f4a2713aSLionel Sambuc if (UseGCC47) {
8039f4a2713aSLionel Sambuc CmdArgs.push_back("-rpath");
8040f4a2713aSLionel Sambuc CmdArgs.push_back("/usr/lib/gcc47");
8041f4a2713aSLionel Sambuc } else {
8042f4a2713aSLionel Sambuc CmdArgs.push_back("-rpath");
8043f4a2713aSLionel Sambuc CmdArgs.push_back("/usr/lib/gcc44");
8044f4a2713aSLionel Sambuc }
8045f4a2713aSLionel Sambuc }
8046f4a2713aSLionel Sambuc
8047f4a2713aSLionel Sambuc if (D.CCCIsCXX()) {
8048f4a2713aSLionel Sambuc getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
8049f4a2713aSLionel Sambuc CmdArgs.push_back("-lm");
8050f4a2713aSLionel Sambuc }
8051f4a2713aSLionel Sambuc
8052f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_pthread))
8053f4a2713aSLionel Sambuc CmdArgs.push_back("-lpthread");
8054f4a2713aSLionel Sambuc
8055f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_nolibc)) {
8056f4a2713aSLionel Sambuc CmdArgs.push_back("-lc");
8057f4a2713aSLionel Sambuc }
8058f4a2713aSLionel Sambuc
8059f4a2713aSLionel Sambuc if (UseGCC47) {
8060f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_static) ||
8061f4a2713aSLionel Sambuc Args.hasArg(options::OPT_static_libgcc)) {
8062f4a2713aSLionel Sambuc CmdArgs.push_back("-lgcc");
8063f4a2713aSLionel Sambuc CmdArgs.push_back("-lgcc_eh");
8064f4a2713aSLionel Sambuc } else {
8065f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_shared_libgcc)) {
8066f4a2713aSLionel Sambuc CmdArgs.push_back("-lgcc_pic");
8067f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_shared))
8068f4a2713aSLionel Sambuc CmdArgs.push_back("-lgcc");
8069f4a2713aSLionel Sambuc } else {
8070f4a2713aSLionel Sambuc CmdArgs.push_back("-lgcc");
8071f4a2713aSLionel Sambuc CmdArgs.push_back("--as-needed");
8072f4a2713aSLionel Sambuc CmdArgs.push_back("-lgcc_pic");
8073f4a2713aSLionel Sambuc CmdArgs.push_back("--no-as-needed");
8074f4a2713aSLionel Sambuc }
8075f4a2713aSLionel Sambuc }
8076f4a2713aSLionel Sambuc } else {
8077f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_shared)) {
8078f4a2713aSLionel Sambuc CmdArgs.push_back("-lgcc_pic");
8079f4a2713aSLionel Sambuc } else {
8080f4a2713aSLionel Sambuc CmdArgs.push_back("-lgcc");
8081f4a2713aSLionel Sambuc }
8082f4a2713aSLionel Sambuc }
8083f4a2713aSLionel Sambuc }
8084f4a2713aSLionel Sambuc
8085f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_nostdlib) &&
8086f4a2713aSLionel Sambuc !Args.hasArg(options::OPT_nostartfiles)) {
8087f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
8088f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(
8089f4a2713aSLionel Sambuc getToolChain().GetFilePath("crtendS.o")));
8090f4a2713aSLionel Sambuc else
8091f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(
8092f4a2713aSLionel Sambuc getToolChain().GetFilePath("crtend.o")));
8093f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(
8094f4a2713aSLionel Sambuc getToolChain().GetFilePath("crtn.o")));
8095f4a2713aSLionel Sambuc }
8096f4a2713aSLionel Sambuc
8097*0a6a1f1dSLionel Sambuc addProfileRT(getToolChain(), Args, CmdArgs);
8098f4a2713aSLionel Sambuc
8099*0a6a1f1dSLionel Sambuc const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
8100*0a6a1f1dSLionel Sambuc C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
8101*0a6a1f1dSLionel Sambuc }
8102*0a6a1f1dSLionel Sambuc
8103*0a6a1f1dSLionel Sambuc // Try to find Exe from a Visual Studio distribution. This first tries to find
8104*0a6a1f1dSLionel Sambuc // an installed copy of Visual Studio and, failing that, looks in the PATH,
8105*0a6a1f1dSLionel Sambuc // making sure that whatever executable that's found is not a same-named exe
8106*0a6a1f1dSLionel Sambuc // from clang itself to prevent clang from falling back to itself.
FindVisualStudioExecutable(const ToolChain & TC,const char * Exe,const char * ClangProgramPath)8107*0a6a1f1dSLionel Sambuc static std::string FindVisualStudioExecutable(const ToolChain &TC,
8108*0a6a1f1dSLionel Sambuc const char *Exe,
8109*0a6a1f1dSLionel Sambuc const char *ClangProgramPath) {
8110*0a6a1f1dSLionel Sambuc const auto &MSVC = static_cast<const toolchains::MSVCToolChain &>(TC);
8111*0a6a1f1dSLionel Sambuc std::string visualStudioBinDir;
8112*0a6a1f1dSLionel Sambuc if (MSVC.getVisualStudioBinariesFolder(ClangProgramPath,
8113*0a6a1f1dSLionel Sambuc visualStudioBinDir)) {
8114*0a6a1f1dSLionel Sambuc SmallString<128> FilePath(visualStudioBinDir);
8115*0a6a1f1dSLionel Sambuc llvm::sys::path::append(FilePath, Exe);
8116*0a6a1f1dSLionel Sambuc if (llvm::sys::fs::can_execute(FilePath.c_str()))
8117*0a6a1f1dSLionel Sambuc return FilePath.str();
8118*0a6a1f1dSLionel Sambuc }
8119*0a6a1f1dSLionel Sambuc
8120*0a6a1f1dSLionel Sambuc return Exe;
8121f4a2713aSLionel Sambuc }
8122f4a2713aSLionel Sambuc
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const8123f4a2713aSLionel Sambuc void visualstudio::Link::ConstructJob(Compilation &C, const JobAction &JA,
8124f4a2713aSLionel Sambuc const InputInfo &Output,
8125f4a2713aSLionel Sambuc const InputInfoList &Inputs,
8126f4a2713aSLionel Sambuc const ArgList &Args,
8127f4a2713aSLionel Sambuc const char *LinkingOutput) const {
8128f4a2713aSLionel Sambuc ArgStringList CmdArgs;
8129*0a6a1f1dSLionel Sambuc const ToolChain &TC = getToolChain();
8130f4a2713aSLionel Sambuc
8131*0a6a1f1dSLionel Sambuc assert((Output.isFilename() || Output.isNothing()) && "invalid output");
8132*0a6a1f1dSLionel Sambuc if (Output.isFilename())
8133f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(std::string("-out:") +
8134f4a2713aSLionel Sambuc Output.getFilename()));
8135f4a2713aSLionel Sambuc
8136f4a2713aSLionel Sambuc if (!Args.hasArg(options::OPT_nostdlib) &&
8137*0a6a1f1dSLionel Sambuc !Args.hasArg(options::OPT_nostartfiles) && !C.getDriver().IsCLMode())
8138f4a2713aSLionel Sambuc CmdArgs.push_back("-defaultlib:libcmt");
8139*0a6a1f1dSLionel Sambuc
8140*0a6a1f1dSLionel Sambuc if (!llvm::sys::Process::GetEnv("LIB")) {
8141*0a6a1f1dSLionel Sambuc // If the VC environment hasn't been configured (perhaps because the user
8142*0a6a1f1dSLionel Sambuc // did not run vcvarsall), try to build a consistent link environment. If
8143*0a6a1f1dSLionel Sambuc // the environment variable is set however, assume the user knows what he's
8144*0a6a1f1dSLionel Sambuc // doing.
8145*0a6a1f1dSLionel Sambuc std::string VisualStudioDir;
8146*0a6a1f1dSLionel Sambuc const auto &MSVC = static_cast<const toolchains::MSVCToolChain &>(TC);
8147*0a6a1f1dSLionel Sambuc if (MSVC.getVisualStudioInstallDir(VisualStudioDir)) {
8148*0a6a1f1dSLionel Sambuc SmallString<128> LibDir(VisualStudioDir);
8149*0a6a1f1dSLionel Sambuc llvm::sys::path::append(LibDir, "VC", "lib");
8150*0a6a1f1dSLionel Sambuc switch (MSVC.getArch()) {
8151*0a6a1f1dSLionel Sambuc case llvm::Triple::x86:
8152*0a6a1f1dSLionel Sambuc // x86 just puts the libraries directly in lib
8153*0a6a1f1dSLionel Sambuc break;
8154*0a6a1f1dSLionel Sambuc case llvm::Triple::x86_64:
8155*0a6a1f1dSLionel Sambuc llvm::sys::path::append(LibDir, "amd64");
8156*0a6a1f1dSLionel Sambuc break;
8157*0a6a1f1dSLionel Sambuc case llvm::Triple::arm:
8158*0a6a1f1dSLionel Sambuc llvm::sys::path::append(LibDir, "arm");
8159*0a6a1f1dSLionel Sambuc break;
8160*0a6a1f1dSLionel Sambuc default:
8161*0a6a1f1dSLionel Sambuc break;
8162*0a6a1f1dSLionel Sambuc }
8163*0a6a1f1dSLionel Sambuc CmdArgs.push_back(
8164*0a6a1f1dSLionel Sambuc Args.MakeArgString(std::string("-libpath:") + LibDir.c_str()));
8165*0a6a1f1dSLionel Sambuc }
8166*0a6a1f1dSLionel Sambuc
8167*0a6a1f1dSLionel Sambuc std::string WindowsSdkLibPath;
8168*0a6a1f1dSLionel Sambuc if (MSVC.getWindowsSDKLibraryPath(WindowsSdkLibPath))
8169*0a6a1f1dSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(std::string("-libpath:") +
8170*0a6a1f1dSLionel Sambuc WindowsSdkLibPath.c_str()));
8171f4a2713aSLionel Sambuc }
8172f4a2713aSLionel Sambuc
8173f4a2713aSLionel Sambuc CmdArgs.push_back("-nologo");
8174f4a2713aSLionel Sambuc
8175*0a6a1f1dSLionel Sambuc if (Args.hasArg(options::OPT_g_Group))
8176*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-debug");
8177f4a2713aSLionel Sambuc
8178*0a6a1f1dSLionel Sambuc bool DLL = Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd);
8179f4a2713aSLionel Sambuc if (DLL) {
8180f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString("-dll"));
8181f4a2713aSLionel Sambuc
8182f4a2713aSLionel Sambuc SmallString<128> ImplibName(Output.getFilename());
8183f4a2713aSLionel Sambuc llvm::sys::path::replace_extension(ImplibName, "lib");
8184f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(std::string("-implib:") +
8185f4a2713aSLionel Sambuc ImplibName.str()));
8186f4a2713aSLionel Sambuc }
8187f4a2713aSLionel Sambuc
8188*0a6a1f1dSLionel Sambuc if (TC.getSanitizerArgs().needsAsanRt()) {
8189f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString("-debug"));
8190f4a2713aSLionel Sambuc CmdArgs.push_back(Args.MakeArgString("-incremental:no"));
8191*0a6a1f1dSLionel Sambuc if (Args.hasArg(options::OPT__SLASH_MD, options::OPT__SLASH_MDd)) {
8192*0a6a1f1dSLionel Sambuc static const char *CompilerRTComponents[] = {
8193*0a6a1f1dSLionel Sambuc "asan_dynamic",
8194*0a6a1f1dSLionel Sambuc "asan_dynamic_runtime_thunk",
8195*0a6a1f1dSLionel Sambuc };
8196*0a6a1f1dSLionel Sambuc for (const auto &Component : CompilerRTComponents)
8197*0a6a1f1dSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(getCompilerRT(TC, Component)));
8198*0a6a1f1dSLionel Sambuc // Make sure the dynamic runtime thunk is not optimized out at link time
8199*0a6a1f1dSLionel Sambuc // to ensure proper SEH handling.
8200*0a6a1f1dSLionel Sambuc CmdArgs.push_back(Args.MakeArgString("-include:___asan_seh_interceptor"));
8201*0a6a1f1dSLionel Sambuc } else if (DLL) {
8202*0a6a1f1dSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(getCompilerRT(TC, "asan_dll_thunk")));
8203f4a2713aSLionel Sambuc } else {
8204*0a6a1f1dSLionel Sambuc static const char *CompilerRTComponents[] = {
8205*0a6a1f1dSLionel Sambuc "asan",
8206*0a6a1f1dSLionel Sambuc "asan_cxx",
8207*0a6a1f1dSLionel Sambuc };
8208*0a6a1f1dSLionel Sambuc for (const auto &Component : CompilerRTComponents)
8209*0a6a1f1dSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(getCompilerRT(TC, Component)));
8210f4a2713aSLionel Sambuc }
8211f4a2713aSLionel Sambuc }
8212f4a2713aSLionel Sambuc
8213f4a2713aSLionel Sambuc Args.AddAllArgValues(CmdArgs, options::OPT__SLASH_link);
8214f4a2713aSLionel Sambuc
8215*0a6a1f1dSLionel Sambuc // Add filenames, libraries, and other linker inputs.
8216*0a6a1f1dSLionel Sambuc for (const auto &Input : Inputs) {
8217*0a6a1f1dSLionel Sambuc if (Input.isFilename()) {
8218*0a6a1f1dSLionel Sambuc CmdArgs.push_back(Input.getFilename());
8219*0a6a1f1dSLionel Sambuc continue;
8220f4a2713aSLionel Sambuc }
8221f4a2713aSLionel Sambuc
8222*0a6a1f1dSLionel Sambuc const Arg &A = Input.getInputArg();
8223*0a6a1f1dSLionel Sambuc
8224*0a6a1f1dSLionel Sambuc // Render -l options differently for the MSVC linker.
8225*0a6a1f1dSLionel Sambuc if (A.getOption().matches(options::OPT_l)) {
8226*0a6a1f1dSLionel Sambuc StringRef Lib = A.getValue();
8227*0a6a1f1dSLionel Sambuc const char *LinkLibArg;
8228*0a6a1f1dSLionel Sambuc if (Lib.endswith(".lib"))
8229*0a6a1f1dSLionel Sambuc LinkLibArg = Args.MakeArgString(Lib);
8230*0a6a1f1dSLionel Sambuc else
8231*0a6a1f1dSLionel Sambuc LinkLibArg = Args.MakeArgString(Lib + ".lib");
8232*0a6a1f1dSLionel Sambuc CmdArgs.push_back(LinkLibArg);
8233*0a6a1f1dSLionel Sambuc continue;
8234*0a6a1f1dSLionel Sambuc }
8235*0a6a1f1dSLionel Sambuc
8236*0a6a1f1dSLionel Sambuc // Otherwise, this is some other kind of linker input option like -Wl, -z,
8237*0a6a1f1dSLionel Sambuc // or -L. Render it, even if MSVC doesn't understand it.
8238*0a6a1f1dSLionel Sambuc A.renderAsInput(Args, CmdArgs);
8239*0a6a1f1dSLionel Sambuc }
8240*0a6a1f1dSLionel Sambuc
8241*0a6a1f1dSLionel Sambuc // We need to special case some linker paths. In the case of lld, we need to
8242*0a6a1f1dSLionel Sambuc // translate 'lld' into 'lld-link', and in the case of the regular msvc
8243*0a6a1f1dSLionel Sambuc // linker, we need to use a special search algorithm.
8244*0a6a1f1dSLionel Sambuc llvm::SmallString<128> linkPath;
8245*0a6a1f1dSLionel Sambuc StringRef Linker = Args.getLastArgValue(options::OPT_fuse_ld_EQ, "link");
8246*0a6a1f1dSLionel Sambuc if (Linker.equals_lower("lld"))
8247*0a6a1f1dSLionel Sambuc Linker = "lld-link";
8248*0a6a1f1dSLionel Sambuc
8249*0a6a1f1dSLionel Sambuc if (Linker.equals_lower("link")) {
8250*0a6a1f1dSLionel Sambuc // If we're using the MSVC linker, it's not sufficient to just use link
8251*0a6a1f1dSLionel Sambuc // from the program PATH, because other environments like GnuWin32 install
8252*0a6a1f1dSLionel Sambuc // their own link.exe which may come first.
8253*0a6a1f1dSLionel Sambuc linkPath = FindVisualStudioExecutable(TC, "link.exe",
8254*0a6a1f1dSLionel Sambuc C.getDriver().getClangProgramPath());
8255*0a6a1f1dSLionel Sambuc } else {
8256*0a6a1f1dSLionel Sambuc linkPath = Linker;
8257*0a6a1f1dSLionel Sambuc llvm::sys::path::replace_extension(linkPath, "exe");
8258*0a6a1f1dSLionel Sambuc linkPath = TC.GetProgramPath(linkPath.c_str());
8259*0a6a1f1dSLionel Sambuc }
8260*0a6a1f1dSLionel Sambuc
8261*0a6a1f1dSLionel Sambuc const char *Exec = Args.MakeArgString(linkPath);
8262*0a6a1f1dSLionel Sambuc C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
8263f4a2713aSLionel Sambuc }
8264f4a2713aSLionel Sambuc
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const8265f4a2713aSLionel Sambuc void visualstudio::Compile::ConstructJob(Compilation &C, const JobAction &JA,
8266f4a2713aSLionel Sambuc const InputInfo &Output,
8267f4a2713aSLionel Sambuc const InputInfoList &Inputs,
8268f4a2713aSLionel Sambuc const ArgList &Args,
8269f4a2713aSLionel Sambuc const char *LinkingOutput) const {
8270f4a2713aSLionel Sambuc C.addCommand(GetCommand(C, JA, Output, Inputs, Args, LinkingOutput));
8271f4a2713aSLionel Sambuc }
8272f4a2713aSLionel Sambuc
GetCommand(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const8273*0a6a1f1dSLionel Sambuc std::unique_ptr<Command> visualstudio::Compile::GetCommand(
8274*0a6a1f1dSLionel Sambuc Compilation &C, const JobAction &JA, const InputInfo &Output,
8275*0a6a1f1dSLionel Sambuc const InputInfoList &Inputs, const ArgList &Args,
8276f4a2713aSLionel Sambuc const char *LinkingOutput) const {
8277f4a2713aSLionel Sambuc ArgStringList CmdArgs;
8278f4a2713aSLionel Sambuc CmdArgs.push_back("/nologo");
8279f4a2713aSLionel Sambuc CmdArgs.push_back("/c"); // Compile only.
8280f4a2713aSLionel Sambuc CmdArgs.push_back("/W0"); // No warnings.
8281f4a2713aSLionel Sambuc
8282f4a2713aSLionel Sambuc // The goal is to be able to invoke this tool correctly based on
8283f4a2713aSLionel Sambuc // any flag accepted by clang-cl.
8284f4a2713aSLionel Sambuc
8285f4a2713aSLionel Sambuc // These are spelled the same way in clang and cl.exe,.
8286f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_D, options::OPT_U);
8287f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_I);
8288f4a2713aSLionel Sambuc
8289f4a2713aSLionel Sambuc // Optimization level.
8290f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_O, options::OPT_O0)) {
8291f4a2713aSLionel Sambuc if (A->getOption().getID() == options::OPT_O0) {
8292f4a2713aSLionel Sambuc CmdArgs.push_back("/Od");
8293f4a2713aSLionel Sambuc } else {
8294f4a2713aSLionel Sambuc StringRef OptLevel = A->getValue();
8295f4a2713aSLionel Sambuc if (OptLevel == "1" || OptLevel == "2" || OptLevel == "s")
8296f4a2713aSLionel Sambuc A->render(Args, CmdArgs);
8297f4a2713aSLionel Sambuc else if (OptLevel == "3")
8298f4a2713aSLionel Sambuc CmdArgs.push_back("/Ox");
8299f4a2713aSLionel Sambuc }
8300f4a2713aSLionel Sambuc }
8301f4a2713aSLionel Sambuc
8302f4a2713aSLionel Sambuc // Flags for which clang-cl have an alias.
8303f4a2713aSLionel Sambuc // FIXME: How can we ensure this stays in sync with relevant clang-cl options?
8304f4a2713aSLionel Sambuc
8305*0a6a1f1dSLionel Sambuc if (Args.hasFlag(options::OPT__SLASH_GR_, options::OPT__SLASH_GR,
8306*0a6a1f1dSLionel Sambuc /*default=*/false))
8307*0a6a1f1dSLionel Sambuc CmdArgs.push_back("/GR-");
8308*0a6a1f1dSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_ffunction_sections,
8309*0a6a1f1dSLionel Sambuc options::OPT_fno_function_sections))
8310*0a6a1f1dSLionel Sambuc CmdArgs.push_back(A->getOption().getID() == options::OPT_ffunction_sections
8311*0a6a1f1dSLionel Sambuc ? "/Gy"
8312*0a6a1f1dSLionel Sambuc : "/Gy-");
8313*0a6a1f1dSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_fdata_sections,
8314*0a6a1f1dSLionel Sambuc options::OPT_fno_data_sections))
8315*0a6a1f1dSLionel Sambuc CmdArgs.push_back(
8316*0a6a1f1dSLionel Sambuc A->getOption().getID() == options::OPT_fdata_sections ? "/Gw" : "/Gw-");
8317f4a2713aSLionel Sambuc if (Args.hasArg(options::OPT_fsyntax_only))
8318f4a2713aSLionel Sambuc CmdArgs.push_back("/Zs");
8319*0a6a1f1dSLionel Sambuc if (Args.hasArg(options::OPT_g_Flag, options::OPT_gline_tables_only))
8320*0a6a1f1dSLionel Sambuc CmdArgs.push_back("/Z7");
8321f4a2713aSLionel Sambuc
8322f4a2713aSLionel Sambuc std::vector<std::string> Includes = Args.getAllArgValues(options::OPT_include);
8323*0a6a1f1dSLionel Sambuc for (const auto &Include : Includes)
8324*0a6a1f1dSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(std::string("/FI") + Include));
8325f4a2713aSLionel Sambuc
8326f4a2713aSLionel Sambuc // Flags that can simply be passed through.
8327f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT__SLASH_LD);
8328f4a2713aSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT__SLASH_LDd);
8329*0a6a1f1dSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT__SLASH_EH);
8330f4a2713aSLionel Sambuc
8331f4a2713aSLionel Sambuc // The order of these flags is relevant, so pick the last one.
8332f4a2713aSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT__SLASH_MD, options::OPT__SLASH_MDd,
8333f4a2713aSLionel Sambuc options::OPT__SLASH_MT, options::OPT__SLASH_MTd))
8334f4a2713aSLionel Sambuc A->render(Args, CmdArgs);
8335f4a2713aSLionel Sambuc
8336f4a2713aSLionel Sambuc
8337f4a2713aSLionel Sambuc // Input filename.
8338f4a2713aSLionel Sambuc assert(Inputs.size() == 1);
8339f4a2713aSLionel Sambuc const InputInfo &II = Inputs[0];
8340f4a2713aSLionel Sambuc assert(II.getType() == types::TY_C || II.getType() == types::TY_CXX);
8341f4a2713aSLionel Sambuc CmdArgs.push_back(II.getType() == types::TY_C ? "/Tc" : "/Tp");
8342f4a2713aSLionel Sambuc if (II.isFilename())
8343f4a2713aSLionel Sambuc CmdArgs.push_back(II.getFilename());
8344f4a2713aSLionel Sambuc else
8345f4a2713aSLionel Sambuc II.getInputArg().renderAsInput(Args, CmdArgs);
8346f4a2713aSLionel Sambuc
8347f4a2713aSLionel Sambuc // Output filename.
8348f4a2713aSLionel Sambuc assert(Output.getType() == types::TY_Object);
8349f4a2713aSLionel Sambuc const char *Fo = Args.MakeArgString(std::string("/Fo") +
8350f4a2713aSLionel Sambuc Output.getFilename());
8351f4a2713aSLionel Sambuc CmdArgs.push_back(Fo);
8352f4a2713aSLionel Sambuc
8353f4a2713aSLionel Sambuc const Driver &D = getToolChain().getDriver();
8354*0a6a1f1dSLionel Sambuc std::string Exec = FindVisualStudioExecutable(getToolChain(), "cl.exe",
8355*0a6a1f1dSLionel Sambuc D.getClangProgramPath());
8356*0a6a1f1dSLionel Sambuc return llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Exec),
8357*0a6a1f1dSLionel Sambuc CmdArgs);
8358f4a2713aSLionel Sambuc }
8359f4a2713aSLionel Sambuc
8360f4a2713aSLionel Sambuc
8361f4a2713aSLionel Sambuc /// XCore Tools
8362f4a2713aSLionel Sambuc // We pass assemble and link construction to the xcc tool.
8363f4a2713aSLionel Sambuc
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const8364f4a2713aSLionel Sambuc void XCore::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
8365f4a2713aSLionel Sambuc const InputInfo &Output,
8366f4a2713aSLionel Sambuc const InputInfoList &Inputs,
8367f4a2713aSLionel Sambuc const ArgList &Args,
8368f4a2713aSLionel Sambuc const char *LinkingOutput) const {
8369*0a6a1f1dSLionel Sambuc claimNoWarnArgs(Args);
8370f4a2713aSLionel Sambuc ArgStringList CmdArgs;
8371f4a2713aSLionel Sambuc
8372f4a2713aSLionel Sambuc CmdArgs.push_back("-o");
8373f4a2713aSLionel Sambuc CmdArgs.push_back(Output.getFilename());
8374f4a2713aSLionel Sambuc
8375f4a2713aSLionel Sambuc CmdArgs.push_back("-c");
8376f4a2713aSLionel Sambuc
8377*0a6a1f1dSLionel Sambuc if (Args.hasArg(options::OPT_v))
8378*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-v");
8379*0a6a1f1dSLionel Sambuc
8380*0a6a1f1dSLionel Sambuc if (Arg *A = Args.getLastArg(options::OPT_g_Group))
8381*0a6a1f1dSLionel Sambuc if (!A->getOption().matches(options::OPT_g0))
8382f4a2713aSLionel Sambuc CmdArgs.push_back("-g");
8383*0a6a1f1dSLionel Sambuc
8384*0a6a1f1dSLionel Sambuc if (Args.hasFlag(options::OPT_fverbose_asm, options::OPT_fno_verbose_asm,
8385*0a6a1f1dSLionel Sambuc false))
8386*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-fverbose-asm");
8387f4a2713aSLionel Sambuc
8388f4a2713aSLionel Sambuc Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
8389f4a2713aSLionel Sambuc options::OPT_Xassembler);
8390f4a2713aSLionel Sambuc
8391*0a6a1f1dSLionel Sambuc for (const auto &II : Inputs)
8392f4a2713aSLionel Sambuc CmdArgs.push_back(II.getFilename());
8393f4a2713aSLionel Sambuc
8394*0a6a1f1dSLionel Sambuc const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("xcc"));
8395*0a6a1f1dSLionel Sambuc C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
8396f4a2713aSLionel Sambuc }
8397f4a2713aSLionel Sambuc
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const8398f4a2713aSLionel Sambuc void XCore::Link::ConstructJob(Compilation &C, const JobAction &JA,
8399f4a2713aSLionel Sambuc const InputInfo &Output,
8400f4a2713aSLionel Sambuc const InputInfoList &Inputs,
8401f4a2713aSLionel Sambuc const ArgList &Args,
8402f4a2713aSLionel Sambuc const char *LinkingOutput) const {
8403f4a2713aSLionel Sambuc ArgStringList CmdArgs;
8404f4a2713aSLionel Sambuc
8405f4a2713aSLionel Sambuc if (Output.isFilename()) {
8406f4a2713aSLionel Sambuc CmdArgs.push_back("-o");
8407f4a2713aSLionel Sambuc CmdArgs.push_back(Output.getFilename());
8408f4a2713aSLionel Sambuc } else {
8409f4a2713aSLionel Sambuc assert(Output.isNothing() && "Invalid output.");
8410f4a2713aSLionel Sambuc }
8411f4a2713aSLionel Sambuc
8412*0a6a1f1dSLionel Sambuc if (Args.hasArg(options::OPT_v))
8413*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-v");
8414*0a6a1f1dSLionel Sambuc
8415*0a6a1f1dSLionel Sambuc if (exceptionSettings(Args, getToolChain().getTriple()))
8416*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-fexceptions");
8417*0a6a1f1dSLionel Sambuc
8418f4a2713aSLionel Sambuc AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
8419f4a2713aSLionel Sambuc
8420*0a6a1f1dSLionel Sambuc const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("xcc"));
8421*0a6a1f1dSLionel Sambuc C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
8422*0a6a1f1dSLionel Sambuc }
8423*0a6a1f1dSLionel Sambuc
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const8424*0a6a1f1dSLionel Sambuc void CrossWindows::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
8425*0a6a1f1dSLionel Sambuc const InputInfo &Output,
8426*0a6a1f1dSLionel Sambuc const InputInfoList &Inputs,
8427*0a6a1f1dSLionel Sambuc const ArgList &Args,
8428*0a6a1f1dSLionel Sambuc const char *LinkingOutput) const {
8429*0a6a1f1dSLionel Sambuc claimNoWarnArgs(Args);
8430*0a6a1f1dSLionel Sambuc const auto &TC =
8431*0a6a1f1dSLionel Sambuc static_cast<const toolchains::CrossWindowsToolChain &>(getToolChain());
8432*0a6a1f1dSLionel Sambuc ArgStringList CmdArgs;
8433*0a6a1f1dSLionel Sambuc const char *Exec;
8434*0a6a1f1dSLionel Sambuc
8435*0a6a1f1dSLionel Sambuc switch (TC.getArch()) {
8436*0a6a1f1dSLionel Sambuc default: llvm_unreachable("unsupported architecture");
8437*0a6a1f1dSLionel Sambuc case llvm::Triple::arm:
8438*0a6a1f1dSLionel Sambuc case llvm::Triple::thumb:
8439*0a6a1f1dSLionel Sambuc break;
8440*0a6a1f1dSLionel Sambuc case llvm::Triple::x86:
8441*0a6a1f1dSLionel Sambuc CmdArgs.push_back("--32");
8442*0a6a1f1dSLionel Sambuc break;
8443*0a6a1f1dSLionel Sambuc case llvm::Triple::x86_64:
8444*0a6a1f1dSLionel Sambuc CmdArgs.push_back("--64");
8445*0a6a1f1dSLionel Sambuc break;
8446*0a6a1f1dSLionel Sambuc }
8447*0a6a1f1dSLionel Sambuc
8448*0a6a1f1dSLionel Sambuc Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
8449*0a6a1f1dSLionel Sambuc
8450*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-o");
8451*0a6a1f1dSLionel Sambuc CmdArgs.push_back(Output.getFilename());
8452*0a6a1f1dSLionel Sambuc
8453*0a6a1f1dSLionel Sambuc for (const auto &Input : Inputs)
8454*0a6a1f1dSLionel Sambuc CmdArgs.push_back(Input.getFilename());
8455*0a6a1f1dSLionel Sambuc
8456*0a6a1f1dSLionel Sambuc const std::string Assembler = TC.GetProgramPath("as");
8457*0a6a1f1dSLionel Sambuc Exec = Args.MakeArgString(Assembler);
8458*0a6a1f1dSLionel Sambuc
8459*0a6a1f1dSLionel Sambuc C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
8460*0a6a1f1dSLionel Sambuc }
8461*0a6a1f1dSLionel Sambuc
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const8462*0a6a1f1dSLionel Sambuc void CrossWindows::Link::ConstructJob(Compilation &C, const JobAction &JA,
8463*0a6a1f1dSLionel Sambuc const InputInfo &Output,
8464*0a6a1f1dSLionel Sambuc const InputInfoList &Inputs,
8465*0a6a1f1dSLionel Sambuc const ArgList &Args,
8466*0a6a1f1dSLionel Sambuc const char *LinkingOutput) const {
8467*0a6a1f1dSLionel Sambuc const auto &TC =
8468*0a6a1f1dSLionel Sambuc static_cast<const toolchains::CrossWindowsToolChain &>(getToolChain());
8469*0a6a1f1dSLionel Sambuc const llvm::Triple &T = TC.getTriple();
8470*0a6a1f1dSLionel Sambuc const Driver &D = TC.getDriver();
8471*0a6a1f1dSLionel Sambuc SmallString<128> EntryPoint;
8472*0a6a1f1dSLionel Sambuc ArgStringList CmdArgs;
8473*0a6a1f1dSLionel Sambuc const char *Exec;
8474*0a6a1f1dSLionel Sambuc
8475*0a6a1f1dSLionel Sambuc // Silence warning for "clang -g foo.o -o foo"
8476*0a6a1f1dSLionel Sambuc Args.ClaimAllArgs(options::OPT_g_Group);
8477*0a6a1f1dSLionel Sambuc // and "clang -emit-llvm foo.o -o foo"
8478*0a6a1f1dSLionel Sambuc Args.ClaimAllArgs(options::OPT_emit_llvm);
8479*0a6a1f1dSLionel Sambuc // and for "clang -w foo.o -o foo"
8480*0a6a1f1dSLionel Sambuc Args.ClaimAllArgs(options::OPT_w);
8481*0a6a1f1dSLionel Sambuc // Other warning options are already handled somewhere else.
8482*0a6a1f1dSLionel Sambuc
8483*0a6a1f1dSLionel Sambuc if (!D.SysRoot.empty())
8484*0a6a1f1dSLionel Sambuc CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
8485*0a6a1f1dSLionel Sambuc
8486*0a6a1f1dSLionel Sambuc if (Args.hasArg(options::OPT_pie))
8487*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-pie");
8488*0a6a1f1dSLionel Sambuc if (Args.hasArg(options::OPT_rdynamic))
8489*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-export-dynamic");
8490*0a6a1f1dSLionel Sambuc if (Args.hasArg(options::OPT_s))
8491*0a6a1f1dSLionel Sambuc CmdArgs.push_back("--strip-all");
8492*0a6a1f1dSLionel Sambuc
8493*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-m");
8494*0a6a1f1dSLionel Sambuc switch (TC.getArch()) {
8495*0a6a1f1dSLionel Sambuc default: llvm_unreachable("unsupported architecture");
8496*0a6a1f1dSLionel Sambuc case llvm::Triple::arm:
8497*0a6a1f1dSLionel Sambuc case llvm::Triple::thumb:
8498*0a6a1f1dSLionel Sambuc // FIXME: this is incorrect for WinCE
8499*0a6a1f1dSLionel Sambuc CmdArgs.push_back("thumb2pe");
8500*0a6a1f1dSLionel Sambuc break;
8501*0a6a1f1dSLionel Sambuc case llvm::Triple::x86:
8502*0a6a1f1dSLionel Sambuc CmdArgs.push_back("i386pe");
8503*0a6a1f1dSLionel Sambuc EntryPoint.append("_");
8504*0a6a1f1dSLionel Sambuc break;
8505*0a6a1f1dSLionel Sambuc case llvm::Triple::x86_64:
8506*0a6a1f1dSLionel Sambuc CmdArgs.push_back("i386pep");
8507*0a6a1f1dSLionel Sambuc break;
8508*0a6a1f1dSLionel Sambuc }
8509*0a6a1f1dSLionel Sambuc
8510*0a6a1f1dSLionel Sambuc if (Args.hasArg(options::OPT_shared)) {
8511*0a6a1f1dSLionel Sambuc switch (T.getArch()) {
8512*0a6a1f1dSLionel Sambuc default: llvm_unreachable("unsupported architecture");
8513*0a6a1f1dSLionel Sambuc case llvm::Triple::arm:
8514*0a6a1f1dSLionel Sambuc case llvm::Triple::thumb:
8515*0a6a1f1dSLionel Sambuc case llvm::Triple::x86_64:
8516*0a6a1f1dSLionel Sambuc EntryPoint.append("_DllMainCRTStartup");
8517*0a6a1f1dSLionel Sambuc break;
8518*0a6a1f1dSLionel Sambuc case llvm::Triple::x86:
8519*0a6a1f1dSLionel Sambuc EntryPoint.append("_DllMainCRTStartup@12");
8520*0a6a1f1dSLionel Sambuc break;
8521*0a6a1f1dSLionel Sambuc }
8522*0a6a1f1dSLionel Sambuc
8523*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-shared");
8524*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-Bdynamic");
8525*0a6a1f1dSLionel Sambuc
8526*0a6a1f1dSLionel Sambuc CmdArgs.push_back("--enable-auto-image-base");
8527*0a6a1f1dSLionel Sambuc
8528*0a6a1f1dSLionel Sambuc CmdArgs.push_back("--entry");
8529*0a6a1f1dSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(EntryPoint));
8530*0a6a1f1dSLionel Sambuc } else {
8531*0a6a1f1dSLionel Sambuc EntryPoint.append("mainCRTStartup");
8532*0a6a1f1dSLionel Sambuc
8533*0a6a1f1dSLionel Sambuc CmdArgs.push_back(Args.hasArg(options::OPT_static) ? "-Bstatic"
8534*0a6a1f1dSLionel Sambuc : "-Bdynamic");
8535*0a6a1f1dSLionel Sambuc
8536*0a6a1f1dSLionel Sambuc if (!Args.hasArg(options::OPT_nostdlib) &&
8537*0a6a1f1dSLionel Sambuc !Args.hasArg(options::OPT_nostartfiles)) {
8538*0a6a1f1dSLionel Sambuc CmdArgs.push_back("--entry");
8539*0a6a1f1dSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(EntryPoint));
8540*0a6a1f1dSLionel Sambuc }
8541*0a6a1f1dSLionel Sambuc
8542*0a6a1f1dSLionel Sambuc // FIXME: handle subsystem
8543*0a6a1f1dSLionel Sambuc }
8544*0a6a1f1dSLionel Sambuc
8545*0a6a1f1dSLionel Sambuc // NOTE: deal with multiple definitions on Windows (e.g. COMDAT)
8546*0a6a1f1dSLionel Sambuc CmdArgs.push_back("--allow-multiple-definition");
8547*0a6a1f1dSLionel Sambuc
8548*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-o");
8549*0a6a1f1dSLionel Sambuc CmdArgs.push_back(Output.getFilename());
8550*0a6a1f1dSLionel Sambuc
8551*0a6a1f1dSLionel Sambuc if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_rdynamic)) {
8552*0a6a1f1dSLionel Sambuc SmallString<261> ImpLib(Output.getFilename());
8553*0a6a1f1dSLionel Sambuc llvm::sys::path::replace_extension(ImpLib, ".lib");
8554*0a6a1f1dSLionel Sambuc
8555*0a6a1f1dSLionel Sambuc CmdArgs.push_back("--out-implib");
8556*0a6a1f1dSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(ImpLib));
8557*0a6a1f1dSLionel Sambuc }
8558*0a6a1f1dSLionel Sambuc
8559*0a6a1f1dSLionel Sambuc if (!Args.hasArg(options::OPT_nostdlib) &&
8560*0a6a1f1dSLionel Sambuc !Args.hasArg(options::OPT_nostartfiles)) {
8561*0a6a1f1dSLionel Sambuc const std::string CRTPath(D.SysRoot + "/usr/lib/");
8562*0a6a1f1dSLionel Sambuc const char *CRTBegin;
8563*0a6a1f1dSLionel Sambuc
8564*0a6a1f1dSLionel Sambuc CRTBegin =
8565*0a6a1f1dSLionel Sambuc Args.hasArg(options::OPT_shared) ? "crtbeginS.obj" : "crtbegin.obj";
8566*0a6a1f1dSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(CRTPath + CRTBegin));
8567*0a6a1f1dSLionel Sambuc }
8568*0a6a1f1dSLionel Sambuc
8569*0a6a1f1dSLionel Sambuc Args.AddAllArgs(CmdArgs, options::OPT_L);
8570*0a6a1f1dSLionel Sambuc
8571*0a6a1f1dSLionel Sambuc const auto &Paths = TC.getFilePaths();
8572*0a6a1f1dSLionel Sambuc for (const auto &Path : Paths)
8573*0a6a1f1dSLionel Sambuc CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + Path));
8574*0a6a1f1dSLionel Sambuc
8575*0a6a1f1dSLionel Sambuc AddLinkerInputs(TC, Inputs, Args, CmdArgs);
8576*0a6a1f1dSLionel Sambuc
8577*0a6a1f1dSLionel Sambuc if (D.CCCIsCXX() && !Args.hasArg(options::OPT_nostdlib) &&
8578*0a6a1f1dSLionel Sambuc !Args.hasArg(options::OPT_nodefaultlibs)) {
8579*0a6a1f1dSLionel Sambuc bool StaticCXX = Args.hasArg(options::OPT_static_libstdcxx) &&
8580*0a6a1f1dSLionel Sambuc !Args.hasArg(options::OPT_static);
8581*0a6a1f1dSLionel Sambuc if (StaticCXX)
8582*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-Bstatic");
8583*0a6a1f1dSLionel Sambuc TC.AddCXXStdlibLibArgs(Args, CmdArgs);
8584*0a6a1f1dSLionel Sambuc if (StaticCXX)
8585*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-Bdynamic");
8586*0a6a1f1dSLionel Sambuc }
8587*0a6a1f1dSLionel Sambuc
8588*0a6a1f1dSLionel Sambuc if (!Args.hasArg(options::OPT_nostdlib)) {
8589*0a6a1f1dSLionel Sambuc if (!Args.hasArg(options::OPT_nodefaultlibs)) {
8590*0a6a1f1dSLionel Sambuc // TODO handle /MT[d] /MD[d]
8591*0a6a1f1dSLionel Sambuc CmdArgs.push_back("-lmsvcrt");
8592*0a6a1f1dSLionel Sambuc AddRunTimeLibs(TC, D, CmdArgs, Args);
8593*0a6a1f1dSLionel Sambuc }
8594*0a6a1f1dSLionel Sambuc }
8595*0a6a1f1dSLionel Sambuc
8596*0a6a1f1dSLionel Sambuc const std::string Linker = TC.GetProgramPath("ld");
8597*0a6a1f1dSLionel Sambuc Exec = Args.MakeArgString(Linker);
8598*0a6a1f1dSLionel Sambuc
8599*0a6a1f1dSLionel Sambuc C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs));
8600f4a2713aSLionel Sambuc }
8601