blob: 89c996ca5a168d5a84eee32d4472d6aa356864e6 [file] [log] [blame]
Nick Lewycky6da90772010-12-31 17:31:54 +00001//===--- ToolChain.cpp - Collections of tools for one platform ------------===//
Daniel Dunbar9e2136d2009-03-16 05:25:36 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Mehdi Amini9670f842016-07-18 19:02:11 +000010#include "clang/Driver/ToolChain.h"
David L. Jonesf561aba2017-03-08 01:02:16 +000011#include "ToolChains/CommonArgs.h"
12#include "ToolChains/Arch/ARM.h"
13#include "ToolChains/Clang.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000014#include "clang/Basic/ObjCRuntime.h"
Pirama Arumuga Nainar65a16dd2017-03-03 23:20:49 +000015#include "clang/Basic/VirtualFileSystem.h"
Jonas Hahnfeldaae83742016-02-12 07:48:37 +000016#include "clang/Config/config.h"
Daniel Dunbar9e2136d2009-03-16 05:25:36 +000017#include "clang/Driver/Action.h"
18#include "clang/Driver/Driver.h"
Daniel Dunbar82eb4ce2010-08-23 22:35:37 +000019#include "clang/Driver/DriverDiagnostic.h"
Daniel Dunbar82eb4ce2010-08-23 22:35:37 +000020#include "clang/Driver/Options.h"
Peter Collingbourne32701642013-11-01 18:16:25 +000021#include "clang/Driver/SanitizerArgs.h"
Dean Michael Berris835832d2017-03-30 00:29:36 +000022#include "clang/Driver/XRayArgs.h"
Logan Chieneb9162f2014-06-26 14:23:45 +000023#include "llvm/ADT/SmallString.h"
Reid Kleckner898229a2013-06-14 17:17:23 +000024#include "llvm/Option/Arg.h"
25#include "llvm/Option/ArgList.h"
26#include "llvm/Option/Option.h"
John McCall24fc0de2011-07-06 00:26:06 +000027#include "llvm/Support/ErrorHandling.h"
Simon Atanasyan08450bd2013-04-20 08:15:03 +000028#include "llvm/Support/FileSystem.h"
Mehdi Amini9670f842016-07-18 19:02:11 +000029#include "llvm/Support/Path.h"
Alexandros Lamprineas89ea4332015-10-28 10:10:03 +000030#include "llvm/Support/TargetParser.h"
Mehdi Amini9670f842016-07-18 19:02:11 +000031#include "llvm/Support/TargetRegistry.h"
Vasileios Kalintiris447e3572015-10-01 16:54:58 +000032
Daniel Dunbar9e2136d2009-03-16 05:25:36 +000033using namespace clang::driver;
Vasileios Kalintiris447e3572015-10-01 16:54:58 +000034using namespace clang::driver::tools;
Chris Lattner0e62c1c2011-07-23 10:55:15 +000035using namespace clang;
Alexandros Lamprineas89ea4332015-10-28 10:10:03 +000036using namespace llvm;
Reid Kleckner898229a2013-06-14 17:17:23 +000037using namespace llvm::opt;
Daniel Dunbar9e2136d2009-03-16 05:25:36 +000038
Filipe Cabecinhasec5d0e62015-02-19 01:04:49 +000039static llvm::opt::Arg *GetRTTIArgument(const ArgList &Args) {
40 return Args.getLastArg(options::OPT_mkernel, options::OPT_fapple_kext,
41 options::OPT_fno_rtti, options::OPT_frtti);
42}
43
44static ToolChain::RTTIMode CalculateRTTIMode(const ArgList &Args,
45 const llvm::Triple &Triple,
46 const Arg *CachedRTTIArg) {
47 // Explicit rtti/no-rtti args
48 if (CachedRTTIArg) {
49 if (CachedRTTIArg->getOption().matches(options::OPT_frtti))
50 return ToolChain::RM_EnabledExplicitly;
51 else
52 return ToolChain::RM_DisabledExplicitly;
53 }
54
55 // -frtti is default, except for the PS4 CPU.
56 if (!Triple.isPS4CPU())
57 return ToolChain::RM_EnabledImplicitly;
58
59 // On the PS4, turning on c++ exceptions turns on rtti.
60 // We're assuming that, if we see -fexceptions, rtti gets turned on.
Filipe Cabecinhas3e707d92015-03-20 23:33:23 +000061 Arg *Exceptions = Args.getLastArgNoClaim(
Filipe Cabecinhasec5d0e62015-02-19 01:04:49 +000062 options::OPT_fcxx_exceptions, options::OPT_fno_cxx_exceptions,
63 options::OPT_fexceptions, options::OPT_fno_exceptions);
64 if (Exceptions &&
65 (Exceptions->getOption().matches(options::OPT_fexceptions) ||
66 Exceptions->getOption().matches(options::OPT_fcxx_exceptions)))
67 return ToolChain::RM_EnabledImplicitly;
68
69 return ToolChain::RM_DisabledImplicitly;
70}
71
Rafael Espindola84b588b2013-03-18 18:10:27 +000072ToolChain::ToolChain(const Driver &D, const llvm::Triple &T,
Jonathan Roelofsb140a102014-10-03 21:57:44 +000073 const ArgList &Args)
Filipe Cabecinhasec5d0e62015-02-19 01:04:49 +000074 : D(D), Triple(T), Args(Args), CachedRTTIArg(GetRTTIArgument(Args)),
Vedant Kumar18286cf2016-07-27 23:02:20 +000075 CachedRTTIMode(CalculateRTTIMode(Args, Triple, CachedRTTIArg)),
76 EffectiveTriple() {
Pirama Arumuga Nainar65a16dd2017-03-03 23:20:49 +000077 std::string CandidateLibPath = getArchSpecificLibPath();
78 if (getVFS().exists(CandidateLibPath))
79 getFilePaths().push_back(CandidateLibPath);
Daniel Dunbar9e2136d2009-03-16 05:25:36 +000080}
81
Angel Garcia Gomez637d1e62015-10-20 13:23:58 +000082ToolChain::~ToolChain() {
83}
Daniel Dunbar9e2136d2009-03-16 05:25:36 +000084
Benjamin Kramerd45b2052015-10-07 15:48:01 +000085vfs::FileSystem &ToolChain::getVFS() const { return getDriver().getVFS(); }
Daniel Dunbar083edf72009-12-21 18:54:17 +000086
Rafael Espindola84b588b2013-03-18 18:10:27 +000087bool ToolChain::useIntegratedAs() const {
Saleem Abdulrasoolcfeb90d2014-02-23 00:40:30 +000088 return Args.hasFlag(options::OPT_fintegrated_as,
89 options::OPT_fno_integrated_as,
Rafael Espindola248e2192013-03-18 17:52:57 +000090 IsIntegratedAssemblerDefault());
91}
92
Alexey Samsonov609213f92013-08-19 09:14:21 +000093const SanitizerArgs& ToolChain::getSanitizerArgs() const {
Peter Collingbourne32701642013-11-01 18:16:25 +000094 if (!SanitizerArguments.get())
95 SanitizerArguments.reset(new SanitizerArgs(*this, Args));
96 return *SanitizerArguments.get();
Alexey Samsonov609213f92013-08-19 09:14:21 +000097}
98
Dean Michael Berris835832d2017-03-30 00:29:36 +000099const XRayArgs& ToolChain::getXRayArgs() const {
100 if (!XRayArguments.get())
101 XRayArguments.reset(new XRayArgs(*this, Args));
102 return *XRayArguments.get();
103}
104
Eric Christopher74a7c5d2015-09-25 17:44:31 +0000105namespace {
106struct DriverSuffix {
107 const char *Suffix;
108 const char *ModeFlag;
109};
110
Serge Pavlov4e769842017-08-29 05:22:26 +0000111const DriverSuffix *FindDriverSuffix(StringRef ProgName, size_t &Pos) {
Eric Christopher74a7c5d2015-09-25 17:44:31 +0000112 // A list of known driver suffixes. Suffixes are compared against the
113 // program name in order. If there is a match, the frontend type is updated as
114 // necessary by applying the ModeFlag.
115 static const DriverSuffix DriverSuffixes[] = {
116 {"clang", nullptr},
117 {"clang++", "--driver-mode=g++"},
118 {"clang-c++", "--driver-mode=g++"},
119 {"clang-cc", nullptr},
120 {"clang-cpp", "--driver-mode=cpp"},
121 {"clang-g++", "--driver-mode=g++"},
122 {"clang-gcc", nullptr},
123 {"clang-cl", "--driver-mode=cl"},
124 {"cc", nullptr},
125 {"cpp", "--driver-mode=cpp"},
126 {"cl", "--driver-mode=cl"},
127 {"++", "--driver-mode=g++"},
128 };
129
Serge Pavlov4e769842017-08-29 05:22:26 +0000130 for (size_t i = 0; i < llvm::array_lengthof(DriverSuffixes); ++i) {
131 StringRef Suffix(DriverSuffixes[i].Suffix);
132 if (ProgName.endswith(Suffix)) {
133 Pos = ProgName.size() - Suffix.size();
Eric Christopher74a7c5d2015-09-25 17:44:31 +0000134 return &DriverSuffixes[i];
Serge Pavlov4e769842017-08-29 05:22:26 +0000135 }
136 }
Eric Christopher74a7c5d2015-09-25 17:44:31 +0000137 return nullptr;
138}
139
140/// Normalize the program name from argv[0] by stripping the file extension if
141/// present and lower-casing the string on Windows.
142std::string normalizeProgramName(llvm::StringRef Argv0) {
143 std::string ProgName = llvm::sys::path::stem(Argv0);
144#ifdef LLVM_ON_WIN32
145 // Transform to lowercase for case insensitive file systems.
146 std::transform(ProgName.begin(), ProgName.end(), ProgName.begin(), ::tolower);
147#endif
148 return ProgName;
149}
150
Serge Pavlov4e769842017-08-29 05:22:26 +0000151const DriverSuffix *parseDriverSuffix(StringRef ProgName, size_t &Pos) {
Eric Christopher74a7c5d2015-09-25 17:44:31 +0000152 // Try to infer frontend type and default target from the program name by
153 // comparing it against DriverSuffixes in order.
154
155 // If there is a match, the function tries to identify a target as prefix.
156 // E.g. "x86_64-linux-clang" as interpreted as suffix "clang" with target
157 // prefix "x86_64-linux". If such a target prefix is found, it may be
158 // added via -target as implicit first argument.
Serge Pavlov4e769842017-08-29 05:22:26 +0000159 const DriverSuffix *DS = FindDriverSuffix(ProgName, Pos);
Eric Christopher74a7c5d2015-09-25 17:44:31 +0000160
161 if (!DS) {
162 // Try again after stripping any trailing version number:
163 // clang++3.5 -> clang++
164 ProgName = ProgName.rtrim("0123456789.");
Serge Pavlov4e769842017-08-29 05:22:26 +0000165 DS = FindDriverSuffix(ProgName, Pos);
Eric Christopher74a7c5d2015-09-25 17:44:31 +0000166 }
167
168 if (!DS) {
169 // Try again after stripping trailing -component.
170 // clang++-tot -> clang++
171 ProgName = ProgName.slice(0, ProgName.rfind('-'));
Serge Pavlov4e769842017-08-29 05:22:26 +0000172 DS = FindDriverSuffix(ProgName, Pos);
Eric Christopher74a7c5d2015-09-25 17:44:31 +0000173 }
174 return DS;
175}
176} // anonymous namespace
177
Serge Pavlov4e769842017-08-29 05:22:26 +0000178ParsedClangName
Eric Christopher74a7c5d2015-09-25 17:44:31 +0000179ToolChain::getTargetAndModeFromProgramName(StringRef PN) {
180 std::string ProgName = normalizeProgramName(PN);
Serge Pavlov4e769842017-08-29 05:22:26 +0000181 size_t SuffixPos;
182 const DriverSuffix *DS = parseDriverSuffix(ProgName, SuffixPos);
Eric Christopher74a7c5d2015-09-25 17:44:31 +0000183 if (!DS)
Serge Pavlov4e769842017-08-29 05:22:26 +0000184 return ParsedClangName();
185 size_t SuffixEnd = SuffixPos + strlen(DS->Suffix);
Eric Christopher74a7c5d2015-09-25 17:44:31 +0000186
Serge Pavlov4e769842017-08-29 05:22:26 +0000187 size_t LastComponent = ProgName.rfind('-', SuffixPos);
Eric Christopher74a7c5d2015-09-25 17:44:31 +0000188 if (LastComponent == std::string::npos)
Serge Pavlov4e769842017-08-29 05:22:26 +0000189 return ParsedClangName(ProgName.substr(0, SuffixEnd), DS->ModeFlag);
190 std::string ModeSuffix = ProgName.substr(LastComponent + 1,
191 SuffixEnd - LastComponent - 1);
Eric Christopher74a7c5d2015-09-25 17:44:31 +0000192
193 // Infer target from the prefix.
194 StringRef Prefix(ProgName);
195 Prefix = Prefix.slice(0, LastComponent);
196 std::string IgnoredError;
Serge Pavlov4e769842017-08-29 05:22:26 +0000197 bool IsRegistered = llvm::TargetRegistry::lookupTarget(Prefix, IgnoredError);
198 return ParsedClangName{Prefix, ModeSuffix, DS->ModeFlag, IsRegistered};
Eric Christopher74a7c5d2015-09-25 17:44:31 +0000199}
200
Rafael Espindola42db11e2014-07-25 19:22:51 +0000201StringRef ToolChain::getDefaultUniversalArchName() const {
Daniel Dunbarc3bd9f52012-11-08 03:38:26 +0000202 // In universal driver terms, the arch name accepted by -arch isn't exactly
203 // the same as the ones that appear in the triple. Roughly speaking, this is
204 // an inverse of the darwin::getArchTypeForDarwinArchName() function, but the
205 // only interesting special case is powerpc.
206 switch (Triple.getArch()) {
207 case llvm::Triple::ppc:
208 return "ppc";
209 case llvm::Triple::ppc64:
210 return "ppc64";
Bill Schmidt778d3872013-07-26 01:36:11 +0000211 case llvm::Triple::ppc64le:
212 return "ppc64le";
Daniel Dunbarc3bd9f52012-11-08 03:38:26 +0000213 default:
214 return Triple.getArchName();
215 }
216}
217
Akira Hatanakab72e35a2017-08-03 23:55:42 +0000218bool ToolChain::IsUnwindTablesDefault(const ArgList &Args) const {
Rafael Espindola151a9572012-09-23 03:05:41 +0000219 return false;
220}
221
Rafael Espindola7cf32212013-03-20 03:05:54 +0000222Tool *ToolChain::getClang() const {
223 if (!Clang)
224 Clang.reset(new tools::Clang(*this));
225 return Clang.get();
226}
227
228Tool *ToolChain::buildAssembler() const {
229 return new tools::ClangAs(*this);
230}
231
232Tool *ToolChain::buildLinker() const {
233 llvm_unreachable("Linking is not supported by this toolchain");
234}
235
236Tool *ToolChain::getAssemble() const {
237 if (!Assemble)
238 Assemble.reset(buildAssembler());
239 return Assemble.get();
240}
241
242Tool *ToolChain::getClangAs() const {
243 if (!Assemble)
244 Assemble.reset(new tools::ClangAs(*this));
245 return Assemble.get();
246}
247
248Tool *ToolChain::getLink() const {
249 if (!Link)
250 Link.reset(buildLinker());
251 return Link.get();
252}
253
Samuel Antao7cab8f12016-10-27 18:04:42 +0000254Tool *ToolChain::getOffloadBundler() const {
255 if (!OffloadBundler)
256 OffloadBundler.reset(new tools::OffloadBundler(*this));
257 return OffloadBundler.get();
258}
259
Rafael Espindola7cf32212013-03-20 03:05:54 +0000260Tool *ToolChain::getTool(Action::ActionClass AC) const {
Rafael Espindolad15a8912013-03-19 00:36:57 +0000261 switch (AC) {
Rafael Espindola7cf32212013-03-20 03:05:54 +0000262 case Action::AssembleJobClass:
263 return getAssemble();
264
265 case Action::LinkJobClass:
266 return getLink();
267
Rafael Espindolad15a8912013-03-19 00:36:57 +0000268 case Action::InputClass:
269 case Action::BindArchClass:
Samuel Antaod06239d2016-07-15 23:13:27 +0000270 case Action::OffloadClass:
Rafael Espindolad15a8912013-03-19 00:36:57 +0000271 case Action::LipoJobClass:
272 case Action::DsymutilJobClass:
Ben Langmuir9b9a8d32014-02-06 18:53:25 +0000273 case Action::VerifyDebugInfoJobClass:
Rafael Espindolad15a8912013-03-19 00:36:57 +0000274 llvm_unreachable("Invalid tool kind.");
275
276 case Action::CompileJobClass:
277 case Action::PrecompileJobClass:
278 case Action::PreprocessJobClass:
279 case Action::AnalyzeJobClass:
280 case Action::MigrateJobClass:
Ben Langmuir9b9a8d32014-02-06 18:53:25 +0000281 case Action::VerifyPCHJobClass:
Bob Wilson23a55f12014-12-21 07:00:00 +0000282 case Action::BackendJobClass:
Rafael Espindola7cf32212013-03-20 03:05:54 +0000283 return getClang();
Samuel Antao69d6f312016-10-27 17:50:43 +0000284
285 case Action::OffloadBundlingJobClass:
Samuel Antaofab4f372016-10-27 18:00:51 +0000286 case Action::OffloadUnbundlingJobClass:
Samuel Antao7cab8f12016-10-27 18:04:42 +0000287 return getOffloadBundler();
Rafael Espindolad15a8912013-03-19 00:36:57 +0000288 }
Benjamin Kramer5fbe2622013-03-21 19:45:46 +0000289
290 llvm_unreachable("Invalid tool kind.");
Rafael Espindolad15a8912013-03-19 00:36:57 +0000291}
292
Vedant Kumar5fb00e42016-07-27 23:01:55 +0000293static StringRef getArchNameForCompilerRTLib(const ToolChain &TC,
294 const ArgList &Args) {
295 const llvm::Triple &Triple = TC.getTriple();
296 bool IsWindows = Triple.isOSWindows();
Vasileios Kalintiris447e3572015-10-01 16:54:58 +0000297
Vasileios Kalintiris447e3572015-10-01 16:54:58 +0000298 if (TC.getArch() == llvm::Triple::arm || TC.getArch() == llvm::Triple::armeb)
Vedant Kumar5fb00e42016-07-27 23:01:55 +0000299 return (arm::getARMFloatABI(TC, Args) == arm::FloatABI::Hard && !IsWindows)
Vasileios Kalintiris447e3572015-10-01 16:54:58 +0000300 ? "armhf"
301 : "arm";
302
Evgeniy Stepanovc6daf73c2017-08-29 22:12:31 +0000303 // For historic reasons, Android library is using i686 instead of i386.
304 if (TC.getArch() == llvm::Triple::x86 && Triple.isAndroid())
305 return "i686";
306
Michal Gorny62dc83b2017-08-28 20:29:52 +0000307 return llvm::Triple::getArchTypeName(TC.getArch());
Vasileios Kalintiris447e3572015-10-01 16:54:58 +0000308}
309
Petr Hosek916a4672017-08-10 04:16:38 +0000310std::string ToolChain::getCompilerRTPath() const {
311 SmallString<128> Path(getDriver().ResourceDir);
Sam Clegg471d7af2017-10-27 18:10:19 +0000312 if (Triple.isOSUnknown()) {
313 llvm::sys::path::append(Path, "lib");
314 } else {
315 StringRef OSLibName = Triple.isOSFreeBSD() ? "freebsd" : getOS();
316 llvm::sys::path::append(Path, "lib", OSLibName);
317 }
Petr Hosek916a4672017-08-10 04:16:38 +0000318 return Path.str();
319}
320
Vedant Kumar5fb00e42016-07-27 23:01:55 +0000321std::string ToolChain::getCompilerRT(const ArgList &Args, StringRef Component,
Vasileios Kalintiris447e3572015-10-01 16:54:58 +0000322 bool Shared) const {
Vedant Kumar5fb00e42016-07-27 23:01:55 +0000323 const llvm::Triple &TT = getTriple();
324 const char *Env = TT.isAndroid() ? "-android" : "";
Saleem Abdulrasool667d6302016-08-31 19:27:07 +0000325 bool IsITANMSVCWindows =
Vedant Kumar5fb00e42016-07-27 23:01:55 +0000326 TT.isWindowsMSVCEnvironment() || TT.isWindowsItaniumEnvironment();
Vasileios Kalintiris447e3572015-10-01 16:54:58 +0000327
Vedant Kumar5fb00e42016-07-27 23:01:55 +0000328 StringRef Arch = getArchNameForCompilerRTLib(*this, Args);
Saleem Abdulrasool667d6302016-08-31 19:27:07 +0000329 const char *Prefix = IsITANMSVCWindows ? "" : "lib";
Vedant Kumar5fb00e42016-07-27 23:01:55 +0000330 const char *Suffix = Shared ? (Triple.isOSWindows() ? ".dll" : ".so")
Saleem Abdulrasool667d6302016-08-31 19:27:07 +0000331 : (IsITANMSVCWindows ? ".lib" : ".a");
Vasileios Kalintiris447e3572015-10-01 16:54:58 +0000332
Petr Hosek916a4672017-08-10 04:16:38 +0000333 SmallString<128> Path(getCompilerRTPath());
Vasileios Kalintiris447e3572015-10-01 16:54:58 +0000334 llvm::sys::path::append(Path, Prefix + Twine("clang_rt.") + Component + "-" +
335 Arch + Env + Suffix);
336 return Path.str();
337}
338
Vedant Kumar5fb00e42016-07-27 23:01:55 +0000339const char *ToolChain::getCompilerRTArgString(const llvm::opt::ArgList &Args,
340 StringRef Component,
341 bool Shared) const {
342 return Args.MakeArgString(getCompilerRT(Args, Component, Shared));
Xinliang David Li69306c02015-10-22 06:15:31 +0000343}
344
Pirama Arumuga Nainar65a16dd2017-03-03 23:20:49 +0000345std::string ToolChain::getArchSpecificLibPath() const {
346 SmallString<128> Path(getDriver().ResourceDir);
347 StringRef OSLibName = getTriple().isOSFreeBSD() ? "freebsd" : getOS();
348 llvm::sys::path::append(Path, "lib", OSLibName,
349 llvm::Triple::getArchTypeName(getArch()));
350 return Path.str();
351}
352
Xinliang David Li69306c02015-10-22 06:15:31 +0000353bool ToolChain::needsProfileRT(const ArgList &Args) {
354 if (Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs,
355 false) ||
356 Args.hasArg(options::OPT_fprofile_generate) ||
357 Args.hasArg(options::OPT_fprofile_generate_EQ) ||
358 Args.hasArg(options::OPT_fprofile_instr_generate) ||
359 Args.hasArg(options::OPT_fprofile_instr_generate_EQ) ||
360 Args.hasArg(options::OPT_fcreate_profile) ||
361 Args.hasArg(options::OPT_coverage))
362 return true;
363
364 return false;
365}
366
Rafael Espindola79764462013-03-24 15:06:53 +0000367Tool *ToolChain::SelectTool(const JobAction &JA) const {
Xinliang David Li69306c02015-10-22 06:15:31 +0000368 if (getDriver().ShouldUseClangCompiler(JA)) return getClang();
Rafael Espindola7cf32212013-03-20 03:05:54 +0000369 Action::ActionClass AC = JA.getKind();
370 if (AC == Action::AssembleJobClass && useIntegratedAs())
Rafael Espindola79764462013-03-24 15:06:53 +0000371 return getClangAs();
372 return getTool(AC);
Rafael Espindola260e28d2013-03-18 20:48:54 +0000373}
374
Daniel Dunbar9c3ed5f2010-07-14 18:46:23 +0000375std::string ToolChain::GetFilePath(const char *Name) const {
Chandler Carruthb65b1112012-01-25 09:12:06 +0000376 return D.GetFilePath(Name, *this);
Daniel Dunbar9e2136d2009-03-16 05:25:36 +0000377}
378
Simon Atanasyanb16488c2012-10-03 19:52:37 +0000379std::string ToolChain::GetProgramPath(const char *Name) const {
380 return D.GetProgramPath(Name, *this);
Daniel Dunbar9e2136d2009-03-16 05:25:36 +0000381}
Daniel Dunbarcc7df6c2010-08-02 05:43:56 +0000382
Logan Chieneb9162f2014-06-26 14:23:45 +0000383std::string ToolChain::GetLinkerPath() const {
Petr Hosekfe2c2b02016-12-14 16:46:50 +0000384 const Arg* A = Args.getLastArg(options::OPT_fuse_ld_EQ);
385 StringRef UseLinker = A ? A->getValue() : CLANG_DEFAULT_LINKER;
Logan Chieneb9162f2014-06-26 14:23:45 +0000386
Petr Hosekfe2c2b02016-12-14 16:46:50 +0000387 if (llvm::sys::path::is_absolute(UseLinker)) {
388 // If we're passed what looks like an absolute path, don't attempt to
389 // second-guess that.
390 if (llvm::sys::fs::exists(UseLinker))
391 return UseLinker;
392 } else if (UseLinker.empty() || UseLinker == "ld") {
393 // If we're passed -fuse-ld= with no argument, or with the argument ld,
394 // then use whatever the default system linker is.
395 return GetProgramPath(getDefaultLinker());
396 } else {
Martell Malonee5639e92017-10-15 17:53:45 +0000397 llvm::SmallString<8> LinkerName;
398 if (Triple.isOSDarwin())
399 LinkerName.append("ld64.");
400 else
401 LinkerName.append("ld.");
Petr Hosekfe2c2b02016-12-14 16:46:50 +0000402 LinkerName.append(UseLinker);
Logan Chieneb9162f2014-06-26 14:23:45 +0000403
Petr Hosekfe2c2b02016-12-14 16:46:50 +0000404 std::string LinkerPath(GetProgramPath(LinkerName.c_str()));
405 if (llvm::sys::fs::exists(LinkerPath))
406 return LinkerPath;
Logan Chieneb9162f2014-06-26 14:23:45 +0000407 }
408
Petr Hosekfe2c2b02016-12-14 16:46:50 +0000409 if (A)
410 getDriver().Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args);
411
412 return GetProgramPath(getDefaultLinker());
Logan Chieneb9162f2014-06-26 14:23:45 +0000413}
414
Mehdi Amini6fcd4eb2016-10-07 21:41:00 +0000415types::ID ToolChain::LookupTypeForExtension(StringRef Ext) const {
Daniel Dunbarcc7df6c2010-08-02 05:43:56 +0000416 return types::lookupTypeForExtension(Ext);
417}
Daniel Dunbar82eb4ce2010-08-23 22:35:37 +0000418
Daniel Dunbar62123a12010-09-17 00:24:52 +0000419bool ToolChain::HasNativeLLVMSupport() const {
420 return false;
421}
422
Richard Barton5828d7b2013-12-17 11:11:25 +0000423bool ToolChain::isCrossCompiling() const {
424 llvm::Triple HostTriple(LLVM_HOST_TRIPLE);
425 switch (HostTriple.getArch()) {
Alp Tokerb164a342013-12-17 17:25:19 +0000426 // The A32/T32/T16 instruction sets are not separate architectures in this
427 // context.
428 case llvm::Triple::arm:
Christian Pirkerf01cd6f2014-03-28 14:40:46 +0000429 case llvm::Triple::armeb:
Alp Tokerb164a342013-12-17 17:25:19 +0000430 case llvm::Triple::thumb:
Christian Pirkerf01cd6f2014-03-28 14:40:46 +0000431 case llvm::Triple::thumbeb:
432 return getArch() != llvm::Triple::arm && getArch() != llvm::Triple::thumb &&
433 getArch() != llvm::Triple::armeb && getArch() != llvm::Triple::thumbeb;
Alp Tokerb164a342013-12-17 17:25:19 +0000434 default:
435 return HostTriple.getArch() != getArch();
Richard Barton5828d7b2013-12-17 11:11:25 +0000436 }
437}
438
John McCall5fb5df92012-06-20 06:18:46 +0000439ObjCRuntime ToolChain::getDefaultObjCRuntime(bool isNonFragile) const {
David Chisnallb601c962012-07-03 20:49:52 +0000440 return ObjCRuntime(isNonFragile ? ObjCRuntime::GNUstep : ObjCRuntime::GCC,
John McCall5fb5df92012-06-20 06:18:46 +0000441 VersionTuple());
John McCall24fc0de2011-07-06 00:26:06 +0000442}
443
Jonathan Roelofsb140a102014-10-03 21:57:44 +0000444bool ToolChain::isThreadModelSupported(const StringRef Model) const {
445 if (Model == "single") {
Dan Gohmanc2853072015-09-03 22:51:53 +0000446 // FIXME: 'single' is only supported on ARM and WebAssembly so far.
Jonathan Roelofsb140a102014-10-03 21:57:44 +0000447 return Triple.getArch() == llvm::Triple::arm ||
448 Triple.getArch() == llvm::Triple::armeb ||
449 Triple.getArch() == llvm::Triple::thumb ||
Dan Gohmanc2853072015-09-03 22:51:53 +0000450 Triple.getArch() == llvm::Triple::thumbeb ||
451 Triple.getArch() == llvm::Triple::wasm32 ||
452 Triple.getArch() == llvm::Triple::wasm64;
Jonathan Roelofsb140a102014-10-03 21:57:44 +0000453 } else if (Model == "posix")
454 return true;
455
456 return false;
457}
458
Jim Grosbach82eee262013-11-16 00:53:35 +0000459std::string ToolChain::ComputeLLVMTriple(const ArgList &Args,
Chad Rosierd3a0f952011-09-20 20:44:06 +0000460 types::ID InputType) const {
Daniel Dunbar82eb4ce2010-08-23 22:35:37 +0000461 switch (getTriple().getArch()) {
462 default:
463 return getTripleString();
464
Jim Grosbach82eee262013-11-16 00:53:35 +0000465 case llvm::Triple::x86_64: {
466 llvm::Triple Triple = getTriple();
Tim Northover157d9112014-01-16 08:48:16 +0000467 if (!Triple.isOSBinFormatMachO())
Jim Grosbach82eee262013-11-16 00:53:35 +0000468 return getTripleString();
469
470 if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
471 // x86_64h goes in the triple. Other -march options just use the
472 // vanilla triple we already have.
473 StringRef MArch = A->getValue();
474 if (MArch == "x86_64h")
475 Triple.setArchName(MArch);
476 }
477 return Triple.getTriple();
478 }
Tim Northover02a979f2014-07-24 10:25:34 +0000479 case llvm::Triple::aarch64: {
480 llvm::Triple Triple = getTriple();
481 if (!Triple.isOSBinFormatMachO())
482 return getTripleString();
483
484 // FIXME: older versions of ld64 expect the "arm64" component in the actual
485 // triple string and query it to determine whether an LTO file can be
486 // handled. Remove this when we don't care any more.
487 Triple.setArchName("arm64");
488 return Triple.getTriple();
489 }
Daniel Dunbar82eb4ce2010-08-23 22:35:37 +0000490 case llvm::Triple::arm:
Christian Pirkerf01cd6f2014-03-28 14:40:46 +0000491 case llvm::Triple::armeb:
492 case llvm::Triple::thumb:
493 case llvm::Triple::thumbeb: {
Daniel Dunbar82eb4ce2010-08-23 22:35:37 +0000494 // FIXME: Factor into subclasses.
495 llvm::Triple Triple = getTriple();
Christian Pirkerf01cd6f2014-03-28 14:40:46 +0000496 bool IsBigEndian = getTriple().getArch() == llvm::Triple::armeb ||
497 getTriple().getArch() == llvm::Triple::thumbeb;
Daniel Dunbar82eb4ce2010-08-23 22:35:37 +0000498
Christian Pirkerba289f02014-04-10 13:59:32 +0000499 // Handle pseudo-target flags '-mlittle-endian'/'-EL' and
500 // '-mbig-endian'/'-EB'.
501 if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian,
502 options::OPT_mbig_endian)) {
David Blaikie7a3cbb22015-03-09 02:02:07 +0000503 IsBigEndian = !A->getOption().matches(options::OPT_mlittle_endian);
Christian Pirkerba289f02014-04-10 13:59:32 +0000504 }
505
Daniel Dunbar82eb4ce2010-08-23 22:35:37 +0000506 // Thumb2 is the default for V7 on Darwin.
507 //
508 // FIXME: Thumb should just be another -target-feaure, not in the triple.
Renato Goline17c5802015-07-27 23:44:42 +0000509 StringRef MCPU, MArch;
510 if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
511 MCPU = A->getValue();
512 if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
513 MArch = A->getValue();
Chandler Carruthd96f37a2015-08-30 07:51:18 +0000514 std::string CPU =
515 Triple.isOSBinFormatMachO()
516 ? tools::arm::getARMCPUForMArch(MArch, Triple).str()
517 : tools::arm::getARMTargetCPU(MCPU, MArch, Triple);
Douglas Katzman96ad05e2015-08-06 22:36:24 +0000518 StringRef Suffix =
Vladimir Sukharev64f68242015-09-23 09:29:32 +0000519 tools::arm::getLLVMArchSuffixForARM(CPU, MArch, Triple);
Florian Hahnef5bbd62017-07-27 16:28:39 +0000520 bool IsMProfile = ARM::parseArchProfile(Suffix) == ARM::ProfileKind::M;
Alexandros Lamprineas89ea4332015-10-28 10:10:03 +0000521 bool ThumbDefault = IsMProfile || (ARM::parseArchVersion(Suffix) == 7 &&
522 getTriple().isOSBinFormatMachO());
Saleem Abdulrasoolf4c9e492014-04-04 20:31:19 +0000523 // FIXME: this is invalid for WindowsCE
524 if (getTriple().isOSWindows())
525 ThumbDefault = true;
Christian Pirkerf01cd6f2014-03-28 14:40:46 +0000526 std::string ArchName;
527 if (IsBigEndian)
528 ArchName = "armeb";
529 else
530 ArchName = "arm";
Chad Rosierd3a0f952011-09-20 20:44:06 +0000531
Florian Hahn83e57c22017-08-04 10:40:18 +0000532 // Check if ARM ISA was explicitly selected (using -mno-thumb or -marm) for
533 // M-Class CPUs/architecture variants, which is not supported.
534 bool ARMModeRequested = !Args.hasFlag(options::OPT_mthumb,
535 options::OPT_mno_thumb, ThumbDefault);
536 if (IsMProfile && ARMModeRequested) {
537 if (!MCPU.empty())
538 getDriver().Diag(diag::err_cpu_unsupported_isa) << CPU << "ARM";
539 else
540 getDriver().Diag(diag::err_arch_unsupported_isa)
541 << tools::arm::getARMArch(MArch, getTriple()) << "ARM";
542 }
543
Peter Smith3947cb32017-11-20 13:43:55 +0000544 // Check to see if an explicit choice to use thumb has been made via
545 // -mthumb. For assembler files we must check for -mthumb in the options
546 // passed to the assember via -Wa or -Xassembler.
547 bool IsThumb = false;
548 if (InputType != types::TY_PP_Asm)
549 IsThumb = Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb,
550 ThumbDefault);
551 else {
552 // Ideally we would check for these flags in
553 // CollectArgsForIntegratedAssembler but we can't change the ArchName at
554 // that point. There is no assembler equivalent of -mno-thumb, -marm, or
555 // -mno-arm.
556 for (const Arg *A :
557 Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) {
558 for (StringRef Value : A->getValues()) {
559 if (Value == "-mthumb")
560 IsThumb = true;
561 }
562 }
563 }
564 // Assembly files should start in ARM mode, unless arch is M-profile, or
565 // -mthumb has been passed explicitly to the assembler. Windows is always
566 // thumb.
567 if (IsThumb || IsMProfile || getTriple().isOSWindows()) {
Christian Pirkerf01cd6f2014-03-28 14:40:46 +0000568 if (IsBigEndian)
569 ArchName = "thumbeb";
570 else
571 ArchName = "thumb";
572 }
Daniel Dunbar82eb4ce2010-08-23 22:35:37 +0000573 Triple.setArchName(ArchName + Suffix.str());
574
575 return Triple.getTriple();
576 }
577 }
578}
579
Douglas Katzman96ad05e2015-08-06 22:36:24 +0000580std::string ToolChain::ComputeEffectiveClangTriple(const ArgList &Args,
Chad Rosierd3a0f952011-09-20 20:44:06 +0000581 types::ID InputType) const {
Chad Rosierd3a0f952011-09-20 20:44:06 +0000582 return ComputeLLVMTriple(Args, InputType);
Daniel Dunbar82eb4ce2010-08-23 22:35:37 +0000583}
584
Chandler Carruth6bfd84f2011-11-04 07:12:53 +0000585void ToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
586 ArgStringList &CC1Args) const {
587 // Each toolchain should provide the appropriate include flags.
588}
589
Gheorghe-Teodor Berceaf0f29602017-07-06 16:22:21 +0000590void ToolChain::addClangTargetOptions(
591 const ArgList &DriverArgs, ArgStringList &CC1Args,
592 Action::OffloadKind DeviceOffloadKind) const {}
Rafael Espindola66aa0452012-06-19 01:26:10 +0000593
Tim Northover336f1892014-03-29 13:16:12 +0000594void ToolChain::addClangWarningOptions(ArgStringList &CC1Args) const {}
595
Vedant Kumar5fb00e42016-07-27 23:01:55 +0000596void ToolChain::addProfileRTLibs(const llvm::opt::ArgList &Args,
Xinliang David Li69306c02015-10-22 06:15:31 +0000597 llvm::opt::ArgStringList &CmdArgs) const {
Vedant Kumar5fb00e42016-07-27 23:01:55 +0000598 if (!needsProfileRT(Args)) return;
Xinliang David Li69306c02015-10-22 06:15:31 +0000599
Vedant Kumar5fb00e42016-07-27 23:01:55 +0000600 CmdArgs.push_back(getCompilerRTArgString(Args, "profile"));
Xinliang David Li69306c02015-10-22 06:15:31 +0000601}
602
Daniel Dunbarf4916cd2011-12-07 23:03:15 +0000603ToolChain::RuntimeLibType ToolChain::GetRuntimeLibType(
Xinliang David Li69306c02015-10-22 06:15:31 +0000604 const ArgList &Args) const {
Jonas Hahnfeldd196fa52016-07-27 08:15:54 +0000605 const Arg* A = Args.getLastArg(options::OPT_rtlib_EQ);
606 StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_RTLIB;
607
Jonas Hahnfeldeb4cc232016-12-12 07:53:47 +0000608 // Only use "platform" in tests to override CLANG_DEFAULT_RTLIB!
Jonas Hahnfeldd196fa52016-07-27 08:15:54 +0000609 if (LibName == "compiler-rt")
610 return ToolChain::RLT_CompilerRT;
611 else if (LibName == "libgcc")
612 return ToolChain::RLT_Libgcc;
613 else if (LibName == "platform")
614 return GetDefaultRuntimeLibType();
615
616 if (A)
617 getDriver().Diag(diag::err_drv_invalid_rtlib_name) << A->getAsString(Args);
Daniel Dunbarf4916cd2011-12-07 23:03:15 +0000618
619 return GetDefaultRuntimeLibType();
620}
621
Daniel Dunbarbf11f792010-09-14 23:12:35 +0000622ToolChain::CXXStdlibType ToolChain::GetCXXStdlibType(const ArgList &Args) const{
Jonas Hahnfeldaae83742016-02-12 07:48:37 +0000623 const Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
Jonas Hahnfeldeb4cc232016-12-12 07:53:47 +0000624 StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_CXX_STDLIB;
Jonas Hahnfeld09954192016-03-14 14:34:04 +0000625
Jonas Hahnfeldeb4cc232016-12-12 07:53:47 +0000626 // Only use "platform" in tests to override CLANG_DEFAULT_CXX_STDLIB!
627 if (LibName == "libc++")
628 return ToolChain::CST_Libcxx;
629 else if (LibName == "libstdc++")
630 return ToolChain::CST_Libstdcxx;
631 else if (LibName == "platform")
632 return GetDefaultCXXStdlibType();
Daniel Dunbar092b6fb2010-09-14 23:12:40 +0000633
Jonas Hahnfeldeb4cc232016-12-12 07:53:47 +0000634 if (A)
635 getDriver().Diag(diag::err_drv_invalid_stdlib_name) << A->getAsString(Args);
Jonas Hahnfeldaae83742016-02-12 07:48:37 +0000636
Jonas Hahnfeldeb4cc232016-12-12 07:53:47 +0000637 return GetDefaultCXXStdlibType();
Daniel Dunbarbf11f792010-09-14 23:12:35 +0000638}
639
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000640/// \brief Utility function to add a system include directory to CC1 arguments.
641/*static*/ void ToolChain::addSystemInclude(const ArgList &DriverArgs,
642 ArgStringList &CC1Args,
643 const Twine &Path) {
644 CC1Args.push_back("-internal-isystem");
645 CC1Args.push_back(DriverArgs.MakeArgString(Path));
646}
647
648/// \brief Utility function to add a system include directory with extern "C"
649/// semantics to CC1 arguments.
650///
651/// Note that this should be used rarely, and only for directories that
652/// historically and for legacy reasons are treated as having implicit extern
653/// "C" semantics. These semantics are *ignored* by and large today, but its
654/// important to preserve the preprocessor changes resulting from the
655/// classification.
656/*static*/ void ToolChain::addExternCSystemInclude(const ArgList &DriverArgs,
657 ArgStringList &CC1Args,
658 const Twine &Path) {
659 CC1Args.push_back("-internal-externc-isystem");
660 CC1Args.push_back(DriverArgs.MakeArgString(Path));
661}
662
Simon Atanasyan08450bd2013-04-20 08:15:03 +0000663void ToolChain::addExternCSystemIncludeIfExists(const ArgList &DriverArgs,
664 ArgStringList &CC1Args,
665 const Twine &Path) {
666 if (llvm::sys::fs::exists(Path))
667 addExternCSystemInclude(DriverArgs, CC1Args, Path);
668}
669
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000670/// \brief Utility function to add a list of system include directories to CC1.
671/*static*/ void ToolChain::addSystemIncludes(const ArgList &DriverArgs,
672 ArgStringList &CC1Args,
673 ArrayRef<StringRef> Paths) {
Douglas Katzman96ad05e2015-08-06 22:36:24 +0000674 for (StringRef Path : Paths) {
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000675 CC1Args.push_back("-internal-isystem");
Douglas Katzman96ad05e2015-08-06 22:36:24 +0000676 CC1Args.push_back(DriverArgs.MakeArgString(Path));
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000677 }
678}
679
Chandler Carruth814db372011-11-04 23:49:01 +0000680void ToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
681 ArgStringList &CC1Args) const {
Chandler Carruth4c81dfa2011-11-04 07:43:33 +0000682 // Header search paths should be handled by each of the subclasses.
683 // Historically, they have not been, and instead have been handled inside of
684 // the CC1-layer frontend. As the logic is hoisted out, this generic function
685 // will slowly stop being called.
686 //
687 // While it is being called, replicate a bit of a hack to propagate the
688 // '-stdlib=' flag down to CC1 so that it can in turn customize the C++
689 // header search paths with it. Once all systems are overriding this
690 // function, the CC1 flag and this line can be removed.
Chandler Carruth814db372011-11-04 23:49:01 +0000691 DriverArgs.AddAllArgs(CC1Args, options::OPT_stdlib_EQ);
Daniel Dunbarbf11f792010-09-14 23:12:35 +0000692}
693
Nico Weber0ee47d92017-07-25 18:02:57 +0000694bool ToolChain::ShouldLinkCXXStdlib(const llvm::opt::ArgList &Args) const {
695 return getDriver().CCCIsCXX() &&
696 !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs,
697 options::OPT_nostdlibxx);
698}
699
Daniel Dunbar3f7796f2010-09-17 01:20:05 +0000700void ToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
701 ArgStringList &CmdArgs) const {
Nico Weber0ee47d92017-07-25 18:02:57 +0000702 assert(!Args.hasArg(options::OPT_nostdlibxx) &&
703 "should not have called this");
Daniel Dunbarbf11f792010-09-14 23:12:35 +0000704 CXXStdlibType Type = GetCXXStdlibType(Args);
705
706 switch (Type) {
Daniel Dunbar092b6fb2010-09-14 23:12:40 +0000707 case ToolChain::CST_Libcxx:
708 CmdArgs.push_back("-lc++");
709 break;
710
Daniel Dunbarbf11f792010-09-14 23:12:35 +0000711 case ToolChain::CST_Libstdcxx:
712 CmdArgs.push_back("-lstdc++");
713 break;
714 }
715}
Shantonu Senafeb03b2010-09-17 18:39:08 +0000716
Douglas Katzman6059ef92015-11-17 17:41:23 +0000717void ToolChain::AddFilePathLibArgs(const ArgList &Args,
718 ArgStringList &CmdArgs) const {
719 for (const auto &LibPath : getFilePaths())
Martell Malone5cad2252015-11-26 01:02:07 +0000720 if(LibPath.length() > 0)
721 CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + LibPath));
Douglas Katzman6059ef92015-11-17 17:41:23 +0000722}
723
Shantonu Senafeb03b2010-09-17 18:39:08 +0000724void ToolChain::AddCCKextLibArgs(const ArgList &Args,
725 ArgStringList &CmdArgs) const {
726 CmdArgs.push_back("-lcc_kext");
727}
Benjamin Kramer058666a2012-10-04 19:42:20 +0000728
729bool ToolChain::AddFastMathRuntimeIfAvailable(const ArgList &Args,
730 ArgStringList &CmdArgs) const {
Benjamin Kramerab88f622014-03-25 18:02:07 +0000731 // Do not check for -fno-fast-math or -fno-unsafe-math when -Ofast passed
732 // (to keep the linker options consistent with gcc and clang itself).
733 if (!isOptimizationLevelFast(Args)) {
734 // Check if -ffast-math or -funsafe-math.
735 Arg *A =
736 Args.getLastArg(options::OPT_ffast_math, options::OPT_fno_fast_math,
737 options::OPT_funsafe_math_optimizations,
738 options::OPT_fno_unsafe_math_optimizations);
Benjamin Kramer058666a2012-10-04 19:42:20 +0000739
Benjamin Kramerab88f622014-03-25 18:02:07 +0000740 if (!A || A->getOption().getID() == options::OPT_fno_fast_math ||
741 A->getOption().getID() == options::OPT_fno_unsafe_math_optimizations)
742 return false;
743 }
Benjamin Kramer058666a2012-10-04 19:42:20 +0000744 // If crtfastmath.o exists add it to the arguments.
745 std::string Path = GetFilePath("crtfastmath.o");
746 if (Path == "crtfastmath.o") // Not found.
747 return false;
748
749 CmdArgs.push_back(Args.MakeArgString(Path));
750 return true;
751}
Alexey Samsonov7f2a0d22015-06-19 21:36:47 +0000752
753SanitizerMask ToolChain::getSupportedSanitizers() const {
754 // Return sanitizers which don't require runtime support and are not
Peter Collingbourne24ec49242015-09-10 19:18:05 +0000755 // platform dependent.
Alexey Samsonov7f2a0d22015-06-19 21:36:47 +0000756 using namespace SanitizerKind;
Peter Collingbourne24ec49242015-09-10 19:18:05 +0000757 SanitizerMask Res = (Undefined & ~Vptr & ~Function) | (CFI & ~CFIICall) |
Vedant Kumar42c17ec2017-03-14 01:56:34 +0000758 CFICastStrict | UnsignedIntegerOverflow | Nullability |
759 LocalBounds;
Peter Collingbourne24ec49242015-09-10 19:18:05 +0000760 if (getTriple().getArch() == llvm::Triple::x86 ||
Derek Schuffef313052016-08-08 21:14:15 +0000761 getTriple().getArch() == llvm::Triple::x86_64 ||
Evgeniy Stepanovda2028b2016-11-11 18:49:49 +0000762 getTriple().getArch() == llvm::Triple::arm ||
763 getTriple().getArch() == llvm::Triple::aarch64 ||
Derek Schuffef313052016-08-08 21:14:15 +0000764 getTriple().getArch() == llvm::Triple::wasm32 ||
765 getTriple().getArch() == llvm::Triple::wasm64)
Peter Collingbourne24ec49242015-09-10 19:18:05 +0000766 Res |= CFIICall;
767 return Res;
Alexey Samsonov7f2a0d22015-06-19 21:36:47 +0000768}
Artem Belevichfa11ab52015-11-17 22:28:46 +0000769
770void ToolChain::AddCudaIncludeArgs(const ArgList &DriverArgs,
771 ArgStringList &CC1Args) const {}
Andrey Turetskiy4798eb62016-06-16 10:36:09 +0000772
773void ToolChain::AddIAMCUIncludeArgs(const ArgList &DriverArgs,
774 ArgStringList &CC1Args) const {}
David L. Jones24fb20c2016-12-07 23:41:58 +0000775
776static VersionTuple separateMSVCFullVersion(unsigned Version) {
777 if (Version < 100)
778 return VersionTuple(Version);
779
780 if (Version < 10000)
781 return VersionTuple(Version / 100, Version % 100);
782
783 unsigned Build = 0, Factor = 1;
784 for (; Version > 10000; Version = Version / 10, Factor = Factor * 10)
785 Build = Build + (Version % 10) * Factor;
786 return VersionTuple(Version / 100, Version % 100, Build);
787}
788
789VersionTuple
790ToolChain::computeMSVCVersion(const Driver *D,
791 const llvm::opt::ArgList &Args) const {
792 const Arg *MSCVersion = Args.getLastArg(options::OPT_fmsc_version);
793 const Arg *MSCompatibilityVersion =
794 Args.getLastArg(options::OPT_fms_compatibility_version);
795
796 if (MSCVersion && MSCompatibilityVersion) {
797 if (D)
798 D->Diag(diag::err_drv_argument_not_allowed_with)
799 << MSCVersion->getAsString(Args)
800 << MSCompatibilityVersion->getAsString(Args);
801 return VersionTuple();
802 }
803
804 if (MSCompatibilityVersion) {
805 VersionTuple MSVT;
806 if (MSVT.tryParse(MSCompatibilityVersion->getValue())) {
807 if (D)
808 D->Diag(diag::err_drv_invalid_value)
809 << MSCompatibilityVersion->getAsString(Args)
810 << MSCompatibilityVersion->getValue();
811 } else {
812 return MSVT;
813 }
814 }
815
816 if (MSCVersion) {
817 unsigned Version = 0;
818 if (StringRef(MSCVersion->getValue()).getAsInteger(10, Version)) {
819 if (D)
820 D->Diag(diag::err_drv_invalid_value)
821 << MSCVersion->getAsString(Args) << MSCVersion->getValue();
822 } else {
823 return separateMSVCFullVersion(Version);
824 }
825 }
826
827 return VersionTuple();
828}
Gheorghe-Teodor Bercea47e0cf32017-08-07 15:39:11 +0000829
Jonas Hahnfeld85f19952017-09-27 18:12:31 +0000830llvm::opt::DerivedArgList *ToolChain::TranslateOpenMPTargetArgs(
Jonas Hahnfeldbbf56fb2017-10-04 13:32:59 +0000831 const llvm::opt::DerivedArgList &Args, bool SameTripleAsHost,
832 SmallVectorImpl<llvm::opt::Arg *> &AllocatedArgs) const {
833 DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
834 const OptTable &Opts = getDriver().getOpts();
835 bool Modified = false;
Gheorghe-Teodor Bercea47e0cf32017-08-07 15:39:11 +0000836
Jonas Hahnfeldbbf56fb2017-10-04 13:32:59 +0000837 // Handle -Xopenmp-target flags
838 for (Arg *A : Args) {
839 // Exclude flags which may only apply to the host toolchain.
840 // Do not exclude flags when the host triple (AuxTriple)
841 // matches the current toolchain triple. If it is not present
842 // at all, target and host share a toolchain.
843 if (A->getOption().matches(options::OPT_m_Group)) {
844 if (SameTripleAsHost)
Gheorghe-Teodor Bercea47e0cf32017-08-07 15:39:11 +0000845 DAL->append(A);
Jonas Hahnfeldbbf56fb2017-10-04 13:32:59 +0000846 else
847 Modified = true;
848 continue;
Gheorghe-Teodor Bercea47e0cf32017-08-07 15:39:11 +0000849 }
850
Jonas Hahnfeldbbf56fb2017-10-04 13:32:59 +0000851 unsigned Index;
852 unsigned Prev;
853 bool XOpenMPTargetNoTriple =
854 A->getOption().matches(options::OPT_Xopenmp_target);
855
856 if (A->getOption().matches(options::OPT_Xopenmp_target_EQ)) {
857 // Passing device args: -Xopenmp-target=<triple> -opt=val.
858 if (A->getValue(0) == getTripleString())
859 Index = Args.getBaseArgs().MakeIndex(A->getValue(1));
860 else
861 continue;
862 } else if (XOpenMPTargetNoTriple) {
863 // Passing device args: -Xopenmp-target -opt=val.
864 Index = Args.getBaseArgs().MakeIndex(A->getValue(0));
Jonas Hahnfeld21b60ed2017-08-14 07:44:05 +0000865 } else {
Jonas Hahnfeldbbf56fb2017-10-04 13:32:59 +0000866 DAL->append(A);
867 continue;
Jonas Hahnfeld21b60ed2017-08-14 07:44:05 +0000868 }
Jonas Hahnfeldbbf56fb2017-10-04 13:32:59 +0000869
870 // Parse the argument to -Xopenmp-target.
871 Prev = Index;
872 std::unique_ptr<Arg> XOpenMPTargetArg(Opts.ParseOneArg(Args, Index));
873 if (!XOpenMPTargetArg || Index > Prev + 1) {
874 getDriver().Diag(diag::err_drv_invalid_Xopenmp_target_with_args)
875 << A->getAsString(Args);
876 continue;
877 }
878 if (XOpenMPTargetNoTriple && XOpenMPTargetArg &&
879 Args.getAllArgValues(options::OPT_fopenmp_targets_EQ).size() != 1) {
880 getDriver().Diag(diag::err_drv_Xopenmp_target_missing_triple);
881 continue;
882 }
883 XOpenMPTargetArg->setBaseArg(A);
884 A = XOpenMPTargetArg.release();
885 AllocatedArgs.push_back(A);
886 DAL->append(A);
887 Modified = true;
Gheorghe-Teodor Bercea47e0cf32017-08-07 15:39:11 +0000888 }
889
Jonas Hahnfeldbbf56fb2017-10-04 13:32:59 +0000890 if (Modified)
891 return DAL;
892
893 delete DAL;
Gheorghe-Teodor Bercea47e0cf32017-08-07 15:39:11 +0000894 return nullptr;
895}