1*67e74705SXin Li //===--- ToolChain.cpp - Collections of tools for one platform ------------===//
2*67e74705SXin Li //
3*67e74705SXin Li // The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===----------------------------------------------------------------------===//
9*67e74705SXin Li
10*67e74705SXin Li #include "Tools.h"
11*67e74705SXin Li #include "clang/Basic/ObjCRuntime.h"
12*67e74705SXin Li #include "clang/Config/config.h"
13*67e74705SXin Li #include "clang/Driver/Action.h"
14*67e74705SXin Li #include "clang/Driver/Driver.h"
15*67e74705SXin Li #include "clang/Driver/DriverDiagnostic.h"
16*67e74705SXin Li #include "clang/Driver/Options.h"
17*67e74705SXin Li #include "clang/Driver/SanitizerArgs.h"
18*67e74705SXin Li #include "clang/Driver/ToolChain.h"
19*67e74705SXin Li #include "llvm/ADT/SmallString.h"
20*67e74705SXin Li #include "llvm/ADT/StringSwitch.h"
21*67e74705SXin Li #include "llvm/Option/Arg.h"
22*67e74705SXin Li #include "llvm/Option/ArgList.h"
23*67e74705SXin Li #include "llvm/Option/Option.h"
24*67e74705SXin Li #include "llvm/Support/ErrorHandling.h"
25*67e74705SXin Li #include "llvm/Support/FileSystem.h"
26*67e74705SXin Li #include "llvm/Support/TargetRegistry.h"
27*67e74705SXin Li #include "llvm/Support/TargetParser.h"
28*67e74705SXin Li
29*67e74705SXin Li using namespace clang::driver;
30*67e74705SXin Li using namespace clang::driver::tools;
31*67e74705SXin Li using namespace clang;
32*67e74705SXin Li using namespace llvm;
33*67e74705SXin Li using namespace llvm::opt;
34*67e74705SXin Li
GetRTTIArgument(const ArgList & Args)35*67e74705SXin Li static llvm::opt::Arg *GetRTTIArgument(const ArgList &Args) {
36*67e74705SXin Li return Args.getLastArg(options::OPT_mkernel, options::OPT_fapple_kext,
37*67e74705SXin Li options::OPT_fno_rtti, options::OPT_frtti);
38*67e74705SXin Li }
39*67e74705SXin Li
CalculateRTTIMode(const ArgList & Args,const llvm::Triple & Triple,const Arg * CachedRTTIArg)40*67e74705SXin Li static ToolChain::RTTIMode CalculateRTTIMode(const ArgList &Args,
41*67e74705SXin Li const llvm::Triple &Triple,
42*67e74705SXin Li const Arg *CachedRTTIArg) {
43*67e74705SXin Li // Explicit rtti/no-rtti args
44*67e74705SXin Li if (CachedRTTIArg) {
45*67e74705SXin Li if (CachedRTTIArg->getOption().matches(options::OPT_frtti))
46*67e74705SXin Li return ToolChain::RM_EnabledExplicitly;
47*67e74705SXin Li else
48*67e74705SXin Li return ToolChain::RM_DisabledExplicitly;
49*67e74705SXin Li }
50*67e74705SXin Li
51*67e74705SXin Li // -frtti is default, except for the PS4 CPU.
52*67e74705SXin Li if (!Triple.isPS4CPU())
53*67e74705SXin Li return ToolChain::RM_EnabledImplicitly;
54*67e74705SXin Li
55*67e74705SXin Li // On the PS4, turning on c++ exceptions turns on rtti.
56*67e74705SXin Li // We're assuming that, if we see -fexceptions, rtti gets turned on.
57*67e74705SXin Li Arg *Exceptions = Args.getLastArgNoClaim(
58*67e74705SXin Li options::OPT_fcxx_exceptions, options::OPT_fno_cxx_exceptions,
59*67e74705SXin Li options::OPT_fexceptions, options::OPT_fno_exceptions);
60*67e74705SXin Li if (Exceptions &&
61*67e74705SXin Li (Exceptions->getOption().matches(options::OPT_fexceptions) ||
62*67e74705SXin Li Exceptions->getOption().matches(options::OPT_fcxx_exceptions)))
63*67e74705SXin Li return ToolChain::RM_EnabledImplicitly;
64*67e74705SXin Li
65*67e74705SXin Li return ToolChain::RM_DisabledImplicitly;
66*67e74705SXin Li }
67*67e74705SXin Li
ToolChain(const Driver & D,const llvm::Triple & T,const ArgList & Args)68*67e74705SXin Li ToolChain::ToolChain(const Driver &D, const llvm::Triple &T,
69*67e74705SXin Li const ArgList &Args)
70*67e74705SXin Li : D(D), Triple(T), Args(Args), CachedRTTIArg(GetRTTIArgument(Args)),
71*67e74705SXin Li CachedRTTIMode(CalculateRTTIMode(Args, Triple, CachedRTTIArg)) {
72*67e74705SXin Li if (Arg *A = Args.getLastArg(options::OPT_mthread_model))
73*67e74705SXin Li if (!isThreadModelSupported(A->getValue()))
74*67e74705SXin Li D.Diag(diag::err_drv_invalid_thread_model_for_target)
75*67e74705SXin Li << A->getValue() << A->getAsString(Args);
76*67e74705SXin Li }
77*67e74705SXin Li
~ToolChain()78*67e74705SXin Li ToolChain::~ToolChain() {
79*67e74705SXin Li }
80*67e74705SXin Li
getVFS() const81*67e74705SXin Li vfs::FileSystem &ToolChain::getVFS() const { return getDriver().getVFS(); }
82*67e74705SXin Li
useIntegratedAs() const83*67e74705SXin Li bool ToolChain::useIntegratedAs() const {
84*67e74705SXin Li return Args.hasFlag(options::OPT_fintegrated_as,
85*67e74705SXin Li options::OPT_fno_integrated_as,
86*67e74705SXin Li IsIntegratedAssemblerDefault());
87*67e74705SXin Li }
88*67e74705SXin Li
getSanitizerArgs() const89*67e74705SXin Li const SanitizerArgs& ToolChain::getSanitizerArgs() const {
90*67e74705SXin Li if (!SanitizerArguments.get())
91*67e74705SXin Li SanitizerArguments.reset(new SanitizerArgs(*this, Args));
92*67e74705SXin Li return *SanitizerArguments.get();
93*67e74705SXin Li }
94*67e74705SXin Li
95*67e74705SXin Li namespace {
96*67e74705SXin Li struct DriverSuffix {
97*67e74705SXin Li const char *Suffix;
98*67e74705SXin Li const char *ModeFlag;
99*67e74705SXin Li };
100*67e74705SXin Li
FindDriverSuffix(StringRef ProgName)101*67e74705SXin Li const DriverSuffix *FindDriverSuffix(StringRef ProgName) {
102*67e74705SXin Li // A list of known driver suffixes. Suffixes are compared against the
103*67e74705SXin Li // program name in order. If there is a match, the frontend type is updated as
104*67e74705SXin Li // necessary by applying the ModeFlag.
105*67e74705SXin Li static const DriverSuffix DriverSuffixes[] = {
106*67e74705SXin Li {"clang", nullptr},
107*67e74705SXin Li {"clang++", "--driver-mode=g++"},
108*67e74705SXin Li {"clang-c++", "--driver-mode=g++"},
109*67e74705SXin Li {"clang-cc", nullptr},
110*67e74705SXin Li {"clang-cpp", "--driver-mode=cpp"},
111*67e74705SXin Li {"clang-g++", "--driver-mode=g++"},
112*67e74705SXin Li {"clang-gcc", nullptr},
113*67e74705SXin Li {"clang-cl", "--driver-mode=cl"},
114*67e74705SXin Li {"cc", nullptr},
115*67e74705SXin Li {"cpp", "--driver-mode=cpp"},
116*67e74705SXin Li {"cl", "--driver-mode=cl"},
117*67e74705SXin Li {"++", "--driver-mode=g++"},
118*67e74705SXin Li };
119*67e74705SXin Li
120*67e74705SXin Li for (size_t i = 0; i < llvm::array_lengthof(DriverSuffixes); ++i)
121*67e74705SXin Li if (ProgName.endswith(DriverSuffixes[i].Suffix))
122*67e74705SXin Li return &DriverSuffixes[i];
123*67e74705SXin Li return nullptr;
124*67e74705SXin Li }
125*67e74705SXin Li
126*67e74705SXin Li /// Normalize the program name from argv[0] by stripping the file extension if
127*67e74705SXin Li /// present and lower-casing the string on Windows.
normalizeProgramName(llvm::StringRef Argv0)128*67e74705SXin Li std::string normalizeProgramName(llvm::StringRef Argv0) {
129*67e74705SXin Li std::string ProgName = llvm::sys::path::stem(Argv0);
130*67e74705SXin Li #ifdef LLVM_ON_WIN32
131*67e74705SXin Li // Transform to lowercase for case insensitive file systems.
132*67e74705SXin Li std::transform(ProgName.begin(), ProgName.end(), ProgName.begin(), ::tolower);
133*67e74705SXin Li #endif
134*67e74705SXin Li return ProgName;
135*67e74705SXin Li }
136*67e74705SXin Li
parseDriverSuffix(StringRef ProgName)137*67e74705SXin Li const DriverSuffix *parseDriverSuffix(StringRef ProgName) {
138*67e74705SXin Li // Try to infer frontend type and default target from the program name by
139*67e74705SXin Li // comparing it against DriverSuffixes in order.
140*67e74705SXin Li
141*67e74705SXin Li // If there is a match, the function tries to identify a target as prefix.
142*67e74705SXin Li // E.g. "x86_64-linux-clang" as interpreted as suffix "clang" with target
143*67e74705SXin Li // prefix "x86_64-linux". If such a target prefix is found, it may be
144*67e74705SXin Li // added via -target as implicit first argument.
145*67e74705SXin Li const DriverSuffix *DS = FindDriverSuffix(ProgName);
146*67e74705SXin Li
147*67e74705SXin Li if (!DS) {
148*67e74705SXin Li // Try again after stripping any trailing version number:
149*67e74705SXin Li // clang++3.5 -> clang++
150*67e74705SXin Li ProgName = ProgName.rtrim("0123456789.");
151*67e74705SXin Li DS = FindDriverSuffix(ProgName);
152*67e74705SXin Li }
153*67e74705SXin Li
154*67e74705SXin Li if (!DS) {
155*67e74705SXin Li // Try again after stripping trailing -component.
156*67e74705SXin Li // clang++-tot -> clang++
157*67e74705SXin Li ProgName = ProgName.slice(0, ProgName.rfind('-'));
158*67e74705SXin Li DS = FindDriverSuffix(ProgName);
159*67e74705SXin Li }
160*67e74705SXin Li return DS;
161*67e74705SXin Li }
162*67e74705SXin Li } // anonymous namespace
163*67e74705SXin Li
164*67e74705SXin Li std::pair<std::string, std::string>
getTargetAndModeFromProgramName(StringRef PN)165*67e74705SXin Li ToolChain::getTargetAndModeFromProgramName(StringRef PN) {
166*67e74705SXin Li std::string ProgName = normalizeProgramName(PN);
167*67e74705SXin Li const DriverSuffix *DS = parseDriverSuffix(ProgName);
168*67e74705SXin Li if (!DS)
169*67e74705SXin Li return std::make_pair("", "");
170*67e74705SXin Li std::string ModeFlag = DS->ModeFlag == nullptr ? "" : DS->ModeFlag;
171*67e74705SXin Li
172*67e74705SXin Li std::string::size_type LastComponent =
173*67e74705SXin Li ProgName.rfind('-', ProgName.size() - strlen(DS->Suffix));
174*67e74705SXin Li if (LastComponent == std::string::npos)
175*67e74705SXin Li return std::make_pair("", ModeFlag);
176*67e74705SXin Li
177*67e74705SXin Li // Infer target from the prefix.
178*67e74705SXin Li StringRef Prefix(ProgName);
179*67e74705SXin Li Prefix = Prefix.slice(0, LastComponent);
180*67e74705SXin Li std::string IgnoredError;
181*67e74705SXin Li std::string Target;
182*67e74705SXin Li if (llvm::TargetRegistry::lookupTarget(Prefix, IgnoredError)) {
183*67e74705SXin Li Target = Prefix;
184*67e74705SXin Li }
185*67e74705SXin Li return std::make_pair(Target, ModeFlag);
186*67e74705SXin Li }
187*67e74705SXin Li
getDefaultUniversalArchName() const188*67e74705SXin Li StringRef ToolChain::getDefaultUniversalArchName() const {
189*67e74705SXin Li // In universal driver terms, the arch name accepted by -arch isn't exactly
190*67e74705SXin Li // the same as the ones that appear in the triple. Roughly speaking, this is
191*67e74705SXin Li // an inverse of the darwin::getArchTypeForDarwinArchName() function, but the
192*67e74705SXin Li // only interesting special case is powerpc.
193*67e74705SXin Li switch (Triple.getArch()) {
194*67e74705SXin Li case llvm::Triple::ppc:
195*67e74705SXin Li return "ppc";
196*67e74705SXin Li case llvm::Triple::ppc64:
197*67e74705SXin Li return "ppc64";
198*67e74705SXin Li case llvm::Triple::ppc64le:
199*67e74705SXin Li return "ppc64le";
200*67e74705SXin Li default:
201*67e74705SXin Li return Triple.getArchName();
202*67e74705SXin Li }
203*67e74705SXin Li }
204*67e74705SXin Li
IsUnwindTablesDefault() const205*67e74705SXin Li bool ToolChain::IsUnwindTablesDefault() const {
206*67e74705SXin Li return false;
207*67e74705SXin Li }
208*67e74705SXin Li
getClang() const209*67e74705SXin Li Tool *ToolChain::getClang() const {
210*67e74705SXin Li if (!Clang)
211*67e74705SXin Li Clang.reset(new tools::Clang(*this));
212*67e74705SXin Li return Clang.get();
213*67e74705SXin Li }
214*67e74705SXin Li
buildAssembler() const215*67e74705SXin Li Tool *ToolChain::buildAssembler() const {
216*67e74705SXin Li return new tools::ClangAs(*this);
217*67e74705SXin Li }
218*67e74705SXin Li
buildLinker() const219*67e74705SXin Li Tool *ToolChain::buildLinker() const {
220*67e74705SXin Li llvm_unreachable("Linking is not supported by this toolchain");
221*67e74705SXin Li }
222*67e74705SXin Li
getAssemble() const223*67e74705SXin Li Tool *ToolChain::getAssemble() const {
224*67e74705SXin Li if (!Assemble)
225*67e74705SXin Li Assemble.reset(buildAssembler());
226*67e74705SXin Li return Assemble.get();
227*67e74705SXin Li }
228*67e74705SXin Li
getClangAs() const229*67e74705SXin Li Tool *ToolChain::getClangAs() const {
230*67e74705SXin Li if (!Assemble)
231*67e74705SXin Li Assemble.reset(new tools::ClangAs(*this));
232*67e74705SXin Li return Assemble.get();
233*67e74705SXin Li }
234*67e74705SXin Li
getLink() const235*67e74705SXin Li Tool *ToolChain::getLink() const {
236*67e74705SXin Li if (!Link)
237*67e74705SXin Li Link.reset(buildLinker());
238*67e74705SXin Li return Link.get();
239*67e74705SXin Li }
240*67e74705SXin Li
getTool(Action::ActionClass AC) const241*67e74705SXin Li Tool *ToolChain::getTool(Action::ActionClass AC) const {
242*67e74705SXin Li switch (AC) {
243*67e74705SXin Li case Action::AssembleJobClass:
244*67e74705SXin Li return getAssemble();
245*67e74705SXin Li
246*67e74705SXin Li case Action::LinkJobClass:
247*67e74705SXin Li return getLink();
248*67e74705SXin Li
249*67e74705SXin Li case Action::InputClass:
250*67e74705SXin Li case Action::BindArchClass:
251*67e74705SXin Li case Action::CudaDeviceClass:
252*67e74705SXin Li case Action::CudaHostClass:
253*67e74705SXin Li case Action::LipoJobClass:
254*67e74705SXin Li case Action::DsymutilJobClass:
255*67e74705SXin Li case Action::VerifyDebugInfoJobClass:
256*67e74705SXin Li llvm_unreachable("Invalid tool kind.");
257*67e74705SXin Li
258*67e74705SXin Li case Action::CompileJobClass:
259*67e74705SXin Li case Action::PrecompileJobClass:
260*67e74705SXin Li case Action::PreprocessJobClass:
261*67e74705SXin Li case Action::AnalyzeJobClass:
262*67e74705SXin Li case Action::MigrateJobClass:
263*67e74705SXin Li case Action::VerifyPCHJobClass:
264*67e74705SXin Li case Action::BackendJobClass:
265*67e74705SXin Li return getClang();
266*67e74705SXin Li }
267*67e74705SXin Li
268*67e74705SXin Li llvm_unreachable("Invalid tool kind.");
269*67e74705SXin Li }
270*67e74705SXin Li
getArchNameForCompilerRTLib(const ToolChain & TC,const ArgList & Args)271*67e74705SXin Li static StringRef getArchNameForCompilerRTLib(const ToolChain &TC,
272*67e74705SXin Li const ArgList &Args) {
273*67e74705SXin Li const llvm::Triple &Triple = TC.getTriple();
274*67e74705SXin Li bool IsWindows = Triple.isOSWindows();
275*67e74705SXin Li
276*67e74705SXin Li if (Triple.isWindowsMSVCEnvironment() && TC.getArch() == llvm::Triple::x86)
277*67e74705SXin Li return "i386";
278*67e74705SXin Li
279*67e74705SXin Li if (TC.getArch() == llvm::Triple::arm || TC.getArch() == llvm::Triple::armeb)
280*67e74705SXin Li return (arm::getARMFloatABI(TC, Args) == arm::FloatABI::Hard && !IsWindows)
281*67e74705SXin Li ? "armhf"
282*67e74705SXin Li : "arm";
283*67e74705SXin Li
284*67e74705SXin Li return TC.getArchName();
285*67e74705SXin Li }
286*67e74705SXin Li
getCompilerRT(const ArgList & Args,StringRef Component,bool Shared) const287*67e74705SXin Li std::string ToolChain::getCompilerRT(const ArgList &Args, StringRef Component,
288*67e74705SXin Li bool Shared) const {
289*67e74705SXin Li const llvm::Triple &TT = getTriple();
290*67e74705SXin Li const char *Env = TT.isAndroid() ? "-android" : "";
291*67e74705SXin Li bool IsITANMSVCWindows =
292*67e74705SXin Li TT.isWindowsMSVCEnvironment() || TT.isWindowsItaniumEnvironment();
293*67e74705SXin Li
294*67e74705SXin Li StringRef Arch = getArchNameForCompilerRTLib(*this, Args);
295*67e74705SXin Li const char *Prefix = IsITANMSVCWindows ? "" : "lib";
296*67e74705SXin Li const char *Suffix = Shared ? (Triple.isOSWindows() ? ".dll" : ".so")
297*67e74705SXin Li : (IsITANMSVCWindows ? ".lib" : ".a");
298*67e74705SXin Li
299*67e74705SXin Li SmallString<128> Path(getDriver().ResourceDir);
300*67e74705SXin Li StringRef OSLibName = Triple.isOSFreeBSD() ? "freebsd" : getOS();
301*67e74705SXin Li llvm::sys::path::append(Path, "lib", OSLibName);
302*67e74705SXin Li llvm::sys::path::append(Path, Prefix + Twine("clang_rt.") + Component + "-" +
303*67e74705SXin Li Arch + Env + Suffix);
304*67e74705SXin Li return Path.str();
305*67e74705SXin Li }
306*67e74705SXin Li
getCompilerRTArgString(const llvm::opt::ArgList & Args,StringRef Component,bool Shared) const307*67e74705SXin Li const char *ToolChain::getCompilerRTArgString(const llvm::opt::ArgList &Args,
308*67e74705SXin Li StringRef Component,
309*67e74705SXin Li bool Shared) const {
310*67e74705SXin Li return Args.MakeArgString(getCompilerRT(Args, Component, Shared));
311*67e74705SXin Li }
312*67e74705SXin Li
needsProfileRT(const ArgList & Args)313*67e74705SXin Li bool ToolChain::needsProfileRT(const ArgList &Args) {
314*67e74705SXin Li if (Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs,
315*67e74705SXin Li false) ||
316*67e74705SXin Li Args.hasArg(options::OPT_fprofile_generate) ||
317*67e74705SXin Li Args.hasArg(options::OPT_fprofile_generate_EQ) ||
318*67e74705SXin Li Args.hasArg(options::OPT_fprofile_instr_generate) ||
319*67e74705SXin Li Args.hasArg(options::OPT_fprofile_instr_generate_EQ) ||
320*67e74705SXin Li Args.hasArg(options::OPT_fcreate_profile) ||
321*67e74705SXin Li Args.hasArg(options::OPT_coverage))
322*67e74705SXin Li return true;
323*67e74705SXin Li
324*67e74705SXin Li return false;
325*67e74705SXin Li }
326*67e74705SXin Li
SelectTool(const JobAction & JA) const327*67e74705SXin Li Tool *ToolChain::SelectTool(const JobAction &JA) const {
328*67e74705SXin Li if (getDriver().ShouldUseClangCompiler(JA)) return getClang();
329*67e74705SXin Li Action::ActionClass AC = JA.getKind();
330*67e74705SXin Li if (AC == Action::AssembleJobClass && useIntegratedAs())
331*67e74705SXin Li return getClangAs();
332*67e74705SXin Li return getTool(AC);
333*67e74705SXin Li }
334*67e74705SXin Li
GetFilePath(const char * Name) const335*67e74705SXin Li std::string ToolChain::GetFilePath(const char *Name) const {
336*67e74705SXin Li return D.GetFilePath(Name, *this);
337*67e74705SXin Li }
338*67e74705SXin Li
GetProgramPath(const char * Name) const339*67e74705SXin Li std::string ToolChain::GetProgramPath(const char *Name) const {
340*67e74705SXin Li return D.GetProgramPath(Name, *this);
341*67e74705SXin Li }
342*67e74705SXin Li
GetLinkerPath() const343*67e74705SXin Li std::string ToolChain::GetLinkerPath() const {
344*67e74705SXin Li if (Arg *A = Args.getLastArg(options::OPT_fuse_ld_EQ)) {
345*67e74705SXin Li StringRef UseLinker = A->getValue();
346*67e74705SXin Li
347*67e74705SXin Li if (llvm::sys::path::is_absolute(UseLinker)) {
348*67e74705SXin Li // If we're passed -fuse-ld= with what looks like an absolute path,
349*67e74705SXin Li // don't attempt to second-guess that.
350*67e74705SXin Li if (llvm::sys::fs::exists(UseLinker))
351*67e74705SXin Li return UseLinker;
352*67e74705SXin Li } else {
353*67e74705SXin Li // If we're passed -fuse-ld= with no argument, or with the argument ld,
354*67e74705SXin Li // then use whatever the default system linker is.
355*67e74705SXin Li if (UseLinker.empty() || UseLinker == "ld")
356*67e74705SXin Li return GetProgramPath("ld");
357*67e74705SXin Li
358*67e74705SXin Li llvm::SmallString<8> LinkerName("ld.");
359*67e74705SXin Li LinkerName.append(UseLinker);
360*67e74705SXin Li
361*67e74705SXin Li std::string LinkerPath(GetProgramPath(LinkerName.c_str()));
362*67e74705SXin Li if (llvm::sys::fs::exists(LinkerPath))
363*67e74705SXin Li return LinkerPath;
364*67e74705SXin Li }
365*67e74705SXin Li
366*67e74705SXin Li getDriver().Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args);
367*67e74705SXin Li return "";
368*67e74705SXin Li }
369*67e74705SXin Li
370*67e74705SXin Li return GetProgramPath(DefaultLinker);
371*67e74705SXin Li }
372*67e74705SXin Li
LookupTypeForExtension(const char * Ext) const373*67e74705SXin Li types::ID ToolChain::LookupTypeForExtension(const char *Ext) const {
374*67e74705SXin Li return types::lookupTypeForExtension(Ext);
375*67e74705SXin Li }
376*67e74705SXin Li
HasNativeLLVMSupport() const377*67e74705SXin Li bool ToolChain::HasNativeLLVMSupport() const {
378*67e74705SXin Li return false;
379*67e74705SXin Li }
380*67e74705SXin Li
isCrossCompiling() const381*67e74705SXin Li bool ToolChain::isCrossCompiling() const {
382*67e74705SXin Li llvm::Triple HostTriple(LLVM_HOST_TRIPLE);
383*67e74705SXin Li switch (HostTriple.getArch()) {
384*67e74705SXin Li // The A32/T32/T16 instruction sets are not separate architectures in this
385*67e74705SXin Li // context.
386*67e74705SXin Li case llvm::Triple::arm:
387*67e74705SXin Li case llvm::Triple::armeb:
388*67e74705SXin Li case llvm::Triple::thumb:
389*67e74705SXin Li case llvm::Triple::thumbeb:
390*67e74705SXin Li return getArch() != llvm::Triple::arm && getArch() != llvm::Triple::thumb &&
391*67e74705SXin Li getArch() != llvm::Triple::armeb && getArch() != llvm::Triple::thumbeb;
392*67e74705SXin Li default:
393*67e74705SXin Li return HostTriple.getArch() != getArch();
394*67e74705SXin Li }
395*67e74705SXin Li }
396*67e74705SXin Li
getDefaultObjCRuntime(bool isNonFragile) const397*67e74705SXin Li ObjCRuntime ToolChain::getDefaultObjCRuntime(bool isNonFragile) const {
398*67e74705SXin Li return ObjCRuntime(isNonFragile ? ObjCRuntime::GNUstep : ObjCRuntime::GCC,
399*67e74705SXin Li VersionTuple());
400*67e74705SXin Li }
401*67e74705SXin Li
isThreadModelSupported(const StringRef Model) const402*67e74705SXin Li bool ToolChain::isThreadModelSupported(const StringRef Model) const {
403*67e74705SXin Li if (Model == "single") {
404*67e74705SXin Li // FIXME: 'single' is only supported on ARM and WebAssembly so far.
405*67e74705SXin Li return Triple.getArch() == llvm::Triple::arm ||
406*67e74705SXin Li Triple.getArch() == llvm::Triple::armeb ||
407*67e74705SXin Li Triple.getArch() == llvm::Triple::thumb ||
408*67e74705SXin Li Triple.getArch() == llvm::Triple::thumbeb ||
409*67e74705SXin Li Triple.getArch() == llvm::Triple::wasm32 ||
410*67e74705SXin Li Triple.getArch() == llvm::Triple::wasm64;
411*67e74705SXin Li } else if (Model == "posix")
412*67e74705SXin Li return true;
413*67e74705SXin Li
414*67e74705SXin Li return false;
415*67e74705SXin Li }
416*67e74705SXin Li
ComputeLLVMTriple(const ArgList & Args,types::ID InputType) const417*67e74705SXin Li std::string ToolChain::ComputeLLVMTriple(const ArgList &Args,
418*67e74705SXin Li types::ID InputType) const {
419*67e74705SXin Li switch (getTriple().getArch()) {
420*67e74705SXin Li default:
421*67e74705SXin Li return getTripleString();
422*67e74705SXin Li
423*67e74705SXin Li case llvm::Triple::x86_64: {
424*67e74705SXin Li llvm::Triple Triple = getTriple();
425*67e74705SXin Li if (!Triple.isOSBinFormatMachO())
426*67e74705SXin Li return getTripleString();
427*67e74705SXin Li
428*67e74705SXin Li if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
429*67e74705SXin Li // x86_64h goes in the triple. Other -march options just use the
430*67e74705SXin Li // vanilla triple we already have.
431*67e74705SXin Li StringRef MArch = A->getValue();
432*67e74705SXin Li if (MArch == "x86_64h")
433*67e74705SXin Li Triple.setArchName(MArch);
434*67e74705SXin Li }
435*67e74705SXin Li return Triple.getTriple();
436*67e74705SXin Li }
437*67e74705SXin Li case llvm::Triple::aarch64: {
438*67e74705SXin Li llvm::Triple Triple = getTriple();
439*67e74705SXin Li if (!Triple.isOSBinFormatMachO())
440*67e74705SXin Li return getTripleString();
441*67e74705SXin Li
442*67e74705SXin Li // FIXME: older versions of ld64 expect the "arm64" component in the actual
443*67e74705SXin Li // triple string and query it to determine whether an LTO file can be
444*67e74705SXin Li // handled. Remove this when we don't care any more.
445*67e74705SXin Li Triple.setArchName("arm64");
446*67e74705SXin Li return Triple.getTriple();
447*67e74705SXin Li }
448*67e74705SXin Li case llvm::Triple::arm:
449*67e74705SXin Li case llvm::Triple::armeb:
450*67e74705SXin Li case llvm::Triple::thumb:
451*67e74705SXin Li case llvm::Triple::thumbeb: {
452*67e74705SXin Li // FIXME: Factor into subclasses.
453*67e74705SXin Li llvm::Triple Triple = getTriple();
454*67e74705SXin Li bool IsBigEndian = getTriple().getArch() == llvm::Triple::armeb ||
455*67e74705SXin Li getTriple().getArch() == llvm::Triple::thumbeb;
456*67e74705SXin Li
457*67e74705SXin Li // Handle pseudo-target flags '-mlittle-endian'/'-EL' and
458*67e74705SXin Li // '-mbig-endian'/'-EB'.
459*67e74705SXin Li if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian,
460*67e74705SXin Li options::OPT_mbig_endian)) {
461*67e74705SXin Li IsBigEndian = !A->getOption().matches(options::OPT_mlittle_endian);
462*67e74705SXin Li }
463*67e74705SXin Li
464*67e74705SXin Li // Thumb2 is the default for V7 on Darwin.
465*67e74705SXin Li //
466*67e74705SXin Li // FIXME: Thumb should just be another -target-feaure, not in the triple.
467*67e74705SXin Li StringRef MCPU, MArch;
468*67e74705SXin Li if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
469*67e74705SXin Li MCPU = A->getValue();
470*67e74705SXin Li if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
471*67e74705SXin Li MArch = A->getValue();
472*67e74705SXin Li std::string CPU =
473*67e74705SXin Li Triple.isOSBinFormatMachO()
474*67e74705SXin Li ? tools::arm::getARMCPUForMArch(MArch, Triple).str()
475*67e74705SXin Li : tools::arm::getARMTargetCPU(MCPU, MArch, Triple);
476*67e74705SXin Li StringRef Suffix =
477*67e74705SXin Li tools::arm::getLLVMArchSuffixForARM(CPU, MArch, Triple);
478*67e74705SXin Li bool IsMProfile = ARM::parseArchProfile(Suffix) == ARM::PK_M;
479*67e74705SXin Li bool ThumbDefault = IsMProfile || (ARM::parseArchVersion(Suffix) == 7 &&
480*67e74705SXin Li getTriple().isOSBinFormatMachO());
481*67e74705SXin Li // FIXME: this is invalid for WindowsCE
482*67e74705SXin Li if (getTriple().isOSWindows())
483*67e74705SXin Li ThumbDefault = true;
484*67e74705SXin Li std::string ArchName;
485*67e74705SXin Li if (IsBigEndian)
486*67e74705SXin Li ArchName = "armeb";
487*67e74705SXin Li else
488*67e74705SXin Li ArchName = "arm";
489*67e74705SXin Li
490*67e74705SXin Li // Assembly files should start in ARM mode, unless arch is M-profile.
491*67e74705SXin Li if ((InputType != types::TY_PP_Asm && Args.hasFlag(options::OPT_mthumb,
492*67e74705SXin Li options::OPT_mno_thumb, ThumbDefault)) || IsMProfile) {
493*67e74705SXin Li if (IsBigEndian)
494*67e74705SXin Li ArchName = "thumbeb";
495*67e74705SXin Li else
496*67e74705SXin Li ArchName = "thumb";
497*67e74705SXin Li }
498*67e74705SXin Li Triple.setArchName(ArchName + Suffix.str());
499*67e74705SXin Li
500*67e74705SXin Li return Triple.getTriple();
501*67e74705SXin Li }
502*67e74705SXin Li }
503*67e74705SXin Li }
504*67e74705SXin Li
ComputeEffectiveClangTriple(const ArgList & Args,types::ID InputType) const505*67e74705SXin Li std::string ToolChain::ComputeEffectiveClangTriple(const ArgList &Args,
506*67e74705SXin Li types::ID InputType) const {
507*67e74705SXin Li return ComputeLLVMTriple(Args, InputType);
508*67e74705SXin Li }
509*67e74705SXin Li
AddClangSystemIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const510*67e74705SXin Li void ToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
511*67e74705SXin Li ArgStringList &CC1Args) const {
512*67e74705SXin Li // Each toolchain should provide the appropriate include flags.
513*67e74705SXin Li }
514*67e74705SXin Li
addClangTargetOptions(const ArgList & DriverArgs,ArgStringList & CC1Args) const515*67e74705SXin Li void ToolChain::addClangTargetOptions(const ArgList &DriverArgs,
516*67e74705SXin Li ArgStringList &CC1Args) const {
517*67e74705SXin Li }
518*67e74705SXin Li
addClangWarningOptions(ArgStringList & CC1Args) const519*67e74705SXin Li void ToolChain::addClangWarningOptions(ArgStringList &CC1Args) const {}
520*67e74705SXin Li
addProfileRTLibs(const llvm::opt::ArgList & Args,llvm::opt::ArgStringList & CmdArgs) const521*67e74705SXin Li void ToolChain::addProfileRTLibs(const llvm::opt::ArgList &Args,
522*67e74705SXin Li llvm::opt::ArgStringList &CmdArgs) const {
523*67e74705SXin Li if (!needsProfileRT(Args)) return;
524*67e74705SXin Li
525*67e74705SXin Li CmdArgs.push_back(getCompilerRTArgString(Args, "profile"));
526*67e74705SXin Li }
527*67e74705SXin Li
GetRuntimeLibType(const ArgList & Args) const528*67e74705SXin Li ToolChain::RuntimeLibType ToolChain::GetRuntimeLibType(
529*67e74705SXin Li const ArgList &Args) const {
530*67e74705SXin Li if (Arg *A = Args.getLastArg(options::OPT_rtlib_EQ)) {
531*67e74705SXin Li StringRef Value = A->getValue();
532*67e74705SXin Li if (Value == "compiler-rt")
533*67e74705SXin Li return ToolChain::RLT_CompilerRT;
534*67e74705SXin Li if (Value == "libgcc")
535*67e74705SXin Li return ToolChain::RLT_Libgcc;
536*67e74705SXin Li getDriver().Diag(diag::err_drv_invalid_rtlib_name)
537*67e74705SXin Li << A->getAsString(Args);
538*67e74705SXin Li }
539*67e74705SXin Li
540*67e74705SXin Li return GetDefaultRuntimeLibType();
541*67e74705SXin Li }
542*67e74705SXin Li
ParseCXXStdlibType(const StringRef & Name,ToolChain::CXXStdlibType & Type)543*67e74705SXin Li static bool ParseCXXStdlibType(const StringRef& Name,
544*67e74705SXin Li ToolChain::CXXStdlibType& Type) {
545*67e74705SXin Li if (Name == "libc++")
546*67e74705SXin Li Type = ToolChain::CST_Libcxx;
547*67e74705SXin Li else if (Name == "libstdc++")
548*67e74705SXin Li Type = ToolChain::CST_Libstdcxx;
549*67e74705SXin Li else
550*67e74705SXin Li return false;
551*67e74705SXin Li
552*67e74705SXin Li return true;
553*67e74705SXin Li }
554*67e74705SXin Li
GetCXXStdlibType(const ArgList & Args) const555*67e74705SXin Li ToolChain::CXXStdlibType ToolChain::GetCXXStdlibType(const ArgList &Args) const{
556*67e74705SXin Li ToolChain::CXXStdlibType Type;
557*67e74705SXin Li bool HasValidType = false;
558*67e74705SXin Li bool ForcePlatformDefault = false;
559*67e74705SXin Li
560*67e74705SXin Li const Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
561*67e74705SXin Li if (A) {
562*67e74705SXin Li StringRef Value = A->getValue();
563*67e74705SXin Li HasValidType = ParseCXXStdlibType(Value, Type);
564*67e74705SXin Li
565*67e74705SXin Li // Only use in tests to override CLANG_DEFAULT_CXX_STDLIB!
566*67e74705SXin Li if (Value == "platform")
567*67e74705SXin Li ForcePlatformDefault = true;
568*67e74705SXin Li else if (!HasValidType)
569*67e74705SXin Li getDriver().Diag(diag::err_drv_invalid_stdlib_name)
570*67e74705SXin Li << A->getAsString(Args);
571*67e74705SXin Li }
572*67e74705SXin Li
573*67e74705SXin Li if (!HasValidType && (ForcePlatformDefault ||
574*67e74705SXin Li !ParseCXXStdlibType(CLANG_DEFAULT_CXX_STDLIB, Type)))
575*67e74705SXin Li Type = GetDefaultCXXStdlibType();
576*67e74705SXin Li
577*67e74705SXin Li return Type;
578*67e74705SXin Li }
579*67e74705SXin Li
580*67e74705SXin Li /// \brief Utility function to add a system include directory to CC1 arguments.
addSystemInclude(const ArgList & DriverArgs,ArgStringList & CC1Args,const Twine & Path)581*67e74705SXin Li /*static*/ void ToolChain::addSystemInclude(const ArgList &DriverArgs,
582*67e74705SXin Li ArgStringList &CC1Args,
583*67e74705SXin Li const Twine &Path) {
584*67e74705SXin Li CC1Args.push_back("-internal-isystem");
585*67e74705SXin Li CC1Args.push_back(DriverArgs.MakeArgString(Path));
586*67e74705SXin Li }
587*67e74705SXin Li
588*67e74705SXin Li /// \brief Utility function to add a system include directory with extern "C"
589*67e74705SXin Li /// semantics to CC1 arguments.
590*67e74705SXin Li ///
591*67e74705SXin Li /// Note that this should be used rarely, and only for directories that
592*67e74705SXin Li /// historically and for legacy reasons are treated as having implicit extern
593*67e74705SXin Li /// "C" semantics. These semantics are *ignored* by and large today, but its
594*67e74705SXin Li /// important to preserve the preprocessor changes resulting from the
595*67e74705SXin Li /// classification.
addExternCSystemInclude(const ArgList & DriverArgs,ArgStringList & CC1Args,const Twine & Path)596*67e74705SXin Li /*static*/ void ToolChain::addExternCSystemInclude(const ArgList &DriverArgs,
597*67e74705SXin Li ArgStringList &CC1Args,
598*67e74705SXin Li const Twine &Path) {
599*67e74705SXin Li CC1Args.push_back("-internal-externc-isystem");
600*67e74705SXin Li CC1Args.push_back(DriverArgs.MakeArgString(Path));
601*67e74705SXin Li }
602*67e74705SXin Li
addExternCSystemIncludeIfExists(const ArgList & DriverArgs,ArgStringList & CC1Args,const Twine & Path)603*67e74705SXin Li void ToolChain::addExternCSystemIncludeIfExists(const ArgList &DriverArgs,
604*67e74705SXin Li ArgStringList &CC1Args,
605*67e74705SXin Li const Twine &Path) {
606*67e74705SXin Li if (llvm::sys::fs::exists(Path))
607*67e74705SXin Li addExternCSystemInclude(DriverArgs, CC1Args, Path);
608*67e74705SXin Li }
609*67e74705SXin Li
610*67e74705SXin Li /// \brief Utility function to add a list of system include directories to CC1.
addSystemIncludes(const ArgList & DriverArgs,ArgStringList & CC1Args,ArrayRef<StringRef> Paths)611*67e74705SXin Li /*static*/ void ToolChain::addSystemIncludes(const ArgList &DriverArgs,
612*67e74705SXin Li ArgStringList &CC1Args,
613*67e74705SXin Li ArrayRef<StringRef> Paths) {
614*67e74705SXin Li for (StringRef Path : Paths) {
615*67e74705SXin Li CC1Args.push_back("-internal-isystem");
616*67e74705SXin Li CC1Args.push_back(DriverArgs.MakeArgString(Path));
617*67e74705SXin Li }
618*67e74705SXin Li }
619*67e74705SXin Li
AddClangCXXStdlibIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const620*67e74705SXin Li void ToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
621*67e74705SXin Li ArgStringList &CC1Args) const {
622*67e74705SXin Li // Header search paths should be handled by each of the subclasses.
623*67e74705SXin Li // Historically, they have not been, and instead have been handled inside of
624*67e74705SXin Li // the CC1-layer frontend. As the logic is hoisted out, this generic function
625*67e74705SXin Li // will slowly stop being called.
626*67e74705SXin Li //
627*67e74705SXin Li // While it is being called, replicate a bit of a hack to propagate the
628*67e74705SXin Li // '-stdlib=' flag down to CC1 so that it can in turn customize the C++
629*67e74705SXin Li // header search paths with it. Once all systems are overriding this
630*67e74705SXin Li // function, the CC1 flag and this line can be removed.
631*67e74705SXin Li DriverArgs.AddAllArgs(CC1Args, options::OPT_stdlib_EQ);
632*67e74705SXin Li }
633*67e74705SXin Li
AddCXXStdlibLibArgs(const ArgList & Args,ArgStringList & CmdArgs) const634*67e74705SXin Li void ToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
635*67e74705SXin Li ArgStringList &CmdArgs) const {
636*67e74705SXin Li CXXStdlibType Type = GetCXXStdlibType(Args);
637*67e74705SXin Li
638*67e74705SXin Li switch (Type) {
639*67e74705SXin Li case ToolChain::CST_Libcxx:
640*67e74705SXin Li CmdArgs.push_back("-lc++");
641*67e74705SXin Li break;
642*67e74705SXin Li
643*67e74705SXin Li case ToolChain::CST_Libstdcxx:
644*67e74705SXin Li CmdArgs.push_back("-lstdc++");
645*67e74705SXin Li break;
646*67e74705SXin Li }
647*67e74705SXin Li }
648*67e74705SXin Li
AddFilePathLibArgs(const ArgList & Args,ArgStringList & CmdArgs) const649*67e74705SXin Li void ToolChain::AddFilePathLibArgs(const ArgList &Args,
650*67e74705SXin Li ArgStringList &CmdArgs) const {
651*67e74705SXin Li for (const auto &LibPath : getFilePaths())
652*67e74705SXin Li if(LibPath.length() > 0)
653*67e74705SXin Li CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + LibPath));
654*67e74705SXin Li }
655*67e74705SXin Li
AddCCKextLibArgs(const ArgList & Args,ArgStringList & CmdArgs) const656*67e74705SXin Li void ToolChain::AddCCKextLibArgs(const ArgList &Args,
657*67e74705SXin Li ArgStringList &CmdArgs) const {
658*67e74705SXin Li CmdArgs.push_back("-lcc_kext");
659*67e74705SXin Li }
660*67e74705SXin Li
AddFastMathRuntimeIfAvailable(const ArgList & Args,ArgStringList & CmdArgs) const661*67e74705SXin Li bool ToolChain::AddFastMathRuntimeIfAvailable(const ArgList &Args,
662*67e74705SXin Li ArgStringList &CmdArgs) const {
663*67e74705SXin Li // Do not check for -fno-fast-math or -fno-unsafe-math when -Ofast passed
664*67e74705SXin Li // (to keep the linker options consistent with gcc and clang itself).
665*67e74705SXin Li if (!isOptimizationLevelFast(Args)) {
666*67e74705SXin Li // Check if -ffast-math or -funsafe-math.
667*67e74705SXin Li Arg *A =
668*67e74705SXin Li Args.getLastArg(options::OPT_ffast_math, options::OPT_fno_fast_math,
669*67e74705SXin Li options::OPT_funsafe_math_optimizations,
670*67e74705SXin Li options::OPT_fno_unsafe_math_optimizations);
671*67e74705SXin Li
672*67e74705SXin Li if (!A || A->getOption().getID() == options::OPT_fno_fast_math ||
673*67e74705SXin Li A->getOption().getID() == options::OPT_fno_unsafe_math_optimizations)
674*67e74705SXin Li return false;
675*67e74705SXin Li }
676*67e74705SXin Li // If crtfastmath.o exists add it to the arguments.
677*67e74705SXin Li std::string Path = GetFilePath("crtfastmath.o");
678*67e74705SXin Li if (Path == "crtfastmath.o") // Not found.
679*67e74705SXin Li return false;
680*67e74705SXin Li
681*67e74705SXin Li CmdArgs.push_back(Args.MakeArgString(Path));
682*67e74705SXin Li return true;
683*67e74705SXin Li }
684*67e74705SXin Li
getSupportedSanitizers() const685*67e74705SXin Li SanitizerMask ToolChain::getSupportedSanitizers() const {
686*67e74705SXin Li // Return sanitizers which don't require runtime support and are not
687*67e74705SXin Li // platform dependent.
688*67e74705SXin Li using namespace SanitizerKind;
689*67e74705SXin Li SanitizerMask Res = (Undefined & ~Vptr & ~Function) | (CFI & ~CFIICall) |
690*67e74705SXin Li CFICastStrict | UnsignedIntegerOverflow | LocalBounds;
691*67e74705SXin Li if (getTriple().getArch() == llvm::Triple::x86 ||
692*67e74705SXin Li getTriple().getArch() == llvm::Triple::x86_64)
693*67e74705SXin Li Res |= CFIICall;
694*67e74705SXin Li return Res;
695*67e74705SXin Li }
696*67e74705SXin Li
AddCudaIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const697*67e74705SXin Li void ToolChain::AddCudaIncludeArgs(const ArgList &DriverArgs,
698*67e74705SXin Li ArgStringList &CC1Args) const {}
699*67e74705SXin Li
AddIAMCUIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const700*67e74705SXin Li void ToolChain::AddIAMCUIncludeArgs(const ArgList &DriverArgs,
701*67e74705SXin Li ArgStringList &CC1Args) const {}
702