ToolChain.cpp 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266
  1. //===- ToolChain.cpp - Collections of tools for one platform --------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #include "clang/Driver/ToolChain.h"
  9. #include "ToolChains/Arch/ARM.h"
  10. #include "ToolChains/Clang.h"
  11. #include "ToolChains/Flang.h"
  12. #include "ToolChains/InterfaceStubs.h"
  13. #include "clang/Basic/ObjCRuntime.h"
  14. #include "clang/Basic/Sanitizers.h"
  15. #include "clang/Config/config.h"
  16. #include "clang/Driver/Action.h"
  17. #include "clang/Driver/Driver.h"
  18. #include "clang/Driver/DriverDiagnostic.h"
  19. #include "clang/Driver/InputInfo.h"
  20. #include "clang/Driver/Job.h"
  21. #include "clang/Driver/Options.h"
  22. #include "clang/Driver/SanitizerArgs.h"
  23. #include "clang/Driver/XRayArgs.h"
  24. #include "llvm/ADT/STLExtras.h"
  25. #include "llvm/ADT/SmallString.h"
  26. #include "llvm/ADT/StringRef.h"
  27. #include "llvm/ADT/Triple.h"
  28. #include "llvm/ADT/Twine.h"
  29. #include "llvm/Config/llvm-config.h"
  30. #include "llvm/MC/MCTargetOptions.h"
  31. #include "llvm/MC/TargetRegistry.h"
  32. #include "llvm/Option/Arg.h"
  33. #include "llvm/Option/ArgList.h"
  34. #include "llvm/Option/OptTable.h"
  35. #include "llvm/Option/Option.h"
  36. #include "llvm/Support/ErrorHandling.h"
  37. #include "llvm/Support/FileSystem.h"
  38. #include "llvm/Support/Path.h"
  39. #include "llvm/Support/TargetParser.h"
  40. #include "llvm/Support/VersionTuple.h"
  41. #include "llvm/Support/VirtualFileSystem.h"
  42. #include <cassert>
  43. #include <cstddef>
  44. #include <cstring>
  45. #include <string>
  46. using namespace clang;
  47. using namespace driver;
  48. using namespace tools;
  49. using namespace llvm;
  50. using namespace llvm::opt;
  51. static llvm::opt::Arg *GetRTTIArgument(const ArgList &Args) {
  52. return Args.getLastArg(options::OPT_mkernel, options::OPT_fapple_kext,
  53. options::OPT_fno_rtti, options::OPT_frtti);
  54. }
  55. static ToolChain::RTTIMode CalculateRTTIMode(const ArgList &Args,
  56. const llvm::Triple &Triple,
  57. const Arg *CachedRTTIArg) {
  58. // Explicit rtti/no-rtti args
  59. if (CachedRTTIArg) {
  60. if (CachedRTTIArg->getOption().matches(options::OPT_frtti))
  61. return ToolChain::RM_Enabled;
  62. else
  63. return ToolChain::RM_Disabled;
  64. }
  65. // -frtti is default, except for the PS4 CPU.
  66. return (Triple.isPS4CPU()) ? ToolChain::RM_Disabled : ToolChain::RM_Enabled;
  67. }
  68. ToolChain::ToolChain(const Driver &D, const llvm::Triple &T,
  69. const ArgList &Args)
  70. : D(D), Triple(T), Args(Args), CachedRTTIArg(GetRTTIArgument(Args)),
  71. CachedRTTIMode(CalculateRTTIMode(Args, Triple, CachedRTTIArg)) {
  72. auto addIfExists = [this](path_list &List, const std::string &Path) {
  73. if (getVFS().exists(Path))
  74. List.push_back(Path);
  75. };
  76. for (const auto &Path : getRuntimePaths())
  77. addIfExists(getLibraryPaths(), Path);
  78. for (const auto &Path : getStdlibPaths())
  79. addIfExists(getFilePaths(), Path);
  80. addIfExists(getFilePaths(), getArchSpecificLibPath());
  81. }
  82. void ToolChain::setTripleEnvironment(llvm::Triple::EnvironmentType Env) {
  83. Triple.setEnvironment(Env);
  84. if (EffectiveTriple != llvm::Triple())
  85. EffectiveTriple.setEnvironment(Env);
  86. }
  87. ToolChain::~ToolChain() = default;
  88. llvm::vfs::FileSystem &ToolChain::getVFS() const {
  89. return getDriver().getVFS();
  90. }
  91. bool ToolChain::useIntegratedAs() const {
  92. return Args.hasFlag(options::OPT_fintegrated_as,
  93. options::OPT_fno_integrated_as,
  94. IsIntegratedAssemblerDefault());
  95. }
  96. bool ToolChain::useRelaxRelocations() const {
  97. return ENABLE_X86_RELAX_RELOCATIONS;
  98. }
  99. bool ToolChain::defaultToIEEELongDouble() const {
  100. return PPC_LINUX_DEFAULT_IEEELONGDOUBLE && getTriple().isOSLinux();
  101. }
  102. SanitizerArgs
  103. ToolChain::getSanitizerArgs(const llvm::opt::ArgList &JobArgs) const {
  104. SanitizerArgs SanArgs(*this, JobArgs, !SanitizerArgsChecked);
  105. SanitizerArgsChecked = true;
  106. return SanArgs;
  107. }
  108. const XRayArgs& ToolChain::getXRayArgs() const {
  109. if (!XRayArguments.get())
  110. XRayArguments.reset(new XRayArgs(*this, Args));
  111. return *XRayArguments.get();
  112. }
  113. namespace {
  114. struct DriverSuffix {
  115. const char *Suffix;
  116. const char *ModeFlag;
  117. };
  118. } // namespace
  119. static const DriverSuffix *FindDriverSuffix(StringRef ProgName, size_t &Pos) {
  120. // A list of known driver suffixes. Suffixes are compared against the
  121. // program name in order. If there is a match, the frontend type is updated as
  122. // necessary by applying the ModeFlag.
  123. static const DriverSuffix DriverSuffixes[] = {
  124. {"clang", nullptr},
  125. {"clang++", "--driver-mode=g++"},
  126. {"clang-c++", "--driver-mode=g++"},
  127. {"clang-cc", nullptr},
  128. {"clang-cpp", "--driver-mode=cpp"},
  129. {"clang-g++", "--driver-mode=g++"},
  130. {"clang-gcc", nullptr},
  131. {"clang-cl", "--driver-mode=cl"},
  132. {"cc", nullptr},
  133. {"cpp", "--driver-mode=cpp"},
  134. {"cl", "--driver-mode=cl"},
  135. {"++", "--driver-mode=g++"},
  136. {"flang", "--driver-mode=flang"},
  137. };
  138. for (size_t i = 0; i < llvm::array_lengthof(DriverSuffixes); ++i) {
  139. StringRef Suffix(DriverSuffixes[i].Suffix);
  140. if (ProgName.endswith(Suffix)) {
  141. Pos = ProgName.size() - Suffix.size();
  142. return &DriverSuffixes[i];
  143. }
  144. }
  145. return nullptr;
  146. }
  147. /// Normalize the program name from argv[0] by stripping the file extension if
  148. /// present and lower-casing the string on Windows.
  149. static std::string normalizeProgramName(llvm::StringRef Argv0) {
  150. std::string ProgName = std::string(llvm::sys::path::stem(Argv0));
  151. if (is_style_windows(llvm::sys::path::Style::native)) {
  152. // Transform to lowercase for case insensitive file systems.
  153. std::transform(ProgName.begin(), ProgName.end(), ProgName.begin(),
  154. ::tolower);
  155. }
  156. return ProgName;
  157. }
  158. static const DriverSuffix *parseDriverSuffix(StringRef ProgName, size_t &Pos) {
  159. // Try to infer frontend type and default target from the program name by
  160. // comparing it against DriverSuffixes in order.
  161. // If there is a match, the function tries to identify a target as prefix.
  162. // E.g. "x86_64-linux-clang" as interpreted as suffix "clang" with target
  163. // prefix "x86_64-linux". If such a target prefix is found, it may be
  164. // added via -target as implicit first argument.
  165. const DriverSuffix *DS = FindDriverSuffix(ProgName, Pos);
  166. if (!DS) {
  167. // Try again after stripping any trailing version number:
  168. // clang++3.5 -> clang++
  169. ProgName = ProgName.rtrim("0123456789.");
  170. DS = FindDriverSuffix(ProgName, Pos);
  171. }
  172. if (!DS) {
  173. // Try again after stripping trailing -component.
  174. // clang++-tot -> clang++
  175. ProgName = ProgName.slice(0, ProgName.rfind('-'));
  176. DS = FindDriverSuffix(ProgName, Pos);
  177. }
  178. return DS;
  179. }
  180. ParsedClangName
  181. ToolChain::getTargetAndModeFromProgramName(StringRef PN) {
  182. std::string ProgName = normalizeProgramName(PN);
  183. size_t SuffixPos;
  184. const DriverSuffix *DS = parseDriverSuffix(ProgName, SuffixPos);
  185. if (!DS)
  186. return {};
  187. size_t SuffixEnd = SuffixPos + strlen(DS->Suffix);
  188. size_t LastComponent = ProgName.rfind('-', SuffixPos);
  189. if (LastComponent == std::string::npos)
  190. return ParsedClangName(ProgName.substr(0, SuffixEnd), DS->ModeFlag);
  191. std::string ModeSuffix = ProgName.substr(LastComponent + 1,
  192. SuffixEnd - LastComponent - 1);
  193. // Infer target from the prefix.
  194. StringRef Prefix(ProgName);
  195. Prefix = Prefix.slice(0, LastComponent);
  196. std::string IgnoredError;
  197. bool IsRegistered =
  198. llvm::TargetRegistry::lookupTarget(std::string(Prefix), IgnoredError);
  199. return ParsedClangName{std::string(Prefix), ModeSuffix, DS->ModeFlag,
  200. IsRegistered};
  201. }
  202. StringRef ToolChain::getDefaultUniversalArchName() const {
  203. // In universal driver terms, the arch name accepted by -arch isn't exactly
  204. // the same as the ones that appear in the triple. Roughly speaking, this is
  205. // an inverse of the darwin::getArchTypeForDarwinArchName() function.
  206. switch (Triple.getArch()) {
  207. case llvm::Triple::aarch64: {
  208. if (getTriple().isArm64e())
  209. return "arm64e";
  210. return "arm64";
  211. }
  212. case llvm::Triple::aarch64_32:
  213. return "arm64_32";
  214. case llvm::Triple::ppc:
  215. return "ppc";
  216. case llvm::Triple::ppcle:
  217. return "ppcle";
  218. case llvm::Triple::ppc64:
  219. return "ppc64";
  220. case llvm::Triple::ppc64le:
  221. return "ppc64le";
  222. default:
  223. return Triple.getArchName();
  224. }
  225. }
  226. std::string ToolChain::getInputFilename(const InputInfo &Input) const {
  227. return Input.getFilename();
  228. }
  229. bool ToolChain::IsUnwindTablesDefault(const ArgList &Args) const {
  230. return false;
  231. }
  232. Tool *ToolChain::getClang() const {
  233. if (!Clang)
  234. Clang.reset(new tools::Clang(*this, useIntegratedBackend()));
  235. return Clang.get();
  236. }
  237. Tool *ToolChain::getFlang() const {
  238. if (!Flang)
  239. Flang.reset(new tools::Flang(*this));
  240. return Flang.get();
  241. }
  242. Tool *ToolChain::buildAssembler() const {
  243. return new tools::ClangAs(*this);
  244. }
  245. Tool *ToolChain::buildLinker() const {
  246. llvm_unreachable("Linking is not supported by this toolchain");
  247. }
  248. Tool *ToolChain::buildStaticLibTool() const {
  249. llvm_unreachable("Creating static lib is not supported by this toolchain");
  250. }
  251. Tool *ToolChain::getAssemble() const {
  252. if (!Assemble)
  253. Assemble.reset(buildAssembler());
  254. return Assemble.get();
  255. }
  256. Tool *ToolChain::getClangAs() const {
  257. if (!Assemble)
  258. Assemble.reset(new tools::ClangAs(*this));
  259. return Assemble.get();
  260. }
  261. Tool *ToolChain::getLink() const {
  262. if (!Link)
  263. Link.reset(buildLinker());
  264. return Link.get();
  265. }
  266. Tool *ToolChain::getStaticLibTool() const {
  267. if (!StaticLibTool)
  268. StaticLibTool.reset(buildStaticLibTool());
  269. return StaticLibTool.get();
  270. }
  271. Tool *ToolChain::getIfsMerge() const {
  272. if (!IfsMerge)
  273. IfsMerge.reset(new tools::ifstool::Merger(*this));
  274. return IfsMerge.get();
  275. }
  276. Tool *ToolChain::getOffloadBundler() const {
  277. if (!OffloadBundler)
  278. OffloadBundler.reset(new tools::OffloadBundler(*this));
  279. return OffloadBundler.get();
  280. }
  281. Tool *ToolChain::getOffloadWrapper() const {
  282. if (!OffloadWrapper)
  283. OffloadWrapper.reset(new tools::OffloadWrapper(*this));
  284. return OffloadWrapper.get();
  285. }
  286. Tool *ToolChain::getLinkerWrapper() const {
  287. if (!LinkerWrapper)
  288. LinkerWrapper.reset(new tools::LinkerWrapper(*this, getLink()));
  289. return LinkerWrapper.get();
  290. }
  291. Tool *ToolChain::getTool(Action::ActionClass AC) const {
  292. switch (AC) {
  293. case Action::AssembleJobClass:
  294. return getAssemble();
  295. case Action::IfsMergeJobClass:
  296. return getIfsMerge();
  297. case Action::LinkJobClass:
  298. return getLink();
  299. case Action::StaticLibJobClass:
  300. return getStaticLibTool();
  301. case Action::InputClass:
  302. case Action::BindArchClass:
  303. case Action::OffloadClass:
  304. case Action::LipoJobClass:
  305. case Action::DsymutilJobClass:
  306. case Action::VerifyDebugInfoJobClass:
  307. llvm_unreachable("Invalid tool kind.");
  308. case Action::CompileJobClass:
  309. case Action::PrecompileJobClass:
  310. case Action::HeaderModulePrecompileJobClass:
  311. case Action::PreprocessJobClass:
  312. case Action::AnalyzeJobClass:
  313. case Action::MigrateJobClass:
  314. case Action::VerifyPCHJobClass:
  315. case Action::BackendJobClass:
  316. return getClang();
  317. case Action::OffloadBundlingJobClass:
  318. case Action::OffloadUnbundlingJobClass:
  319. return getOffloadBundler();
  320. case Action::OffloadWrapperJobClass:
  321. return getOffloadWrapper();
  322. case Action::LinkerWrapperJobClass:
  323. return getLinkerWrapper();
  324. }
  325. llvm_unreachable("Invalid tool kind.");
  326. }
  327. static StringRef getArchNameForCompilerRTLib(const ToolChain &TC,
  328. const ArgList &Args) {
  329. const llvm::Triple &Triple = TC.getTriple();
  330. bool IsWindows = Triple.isOSWindows();
  331. if (TC.getArch() == llvm::Triple::arm || TC.getArch() == llvm::Triple::armeb)
  332. return (arm::getARMFloatABI(TC, Args) == arm::FloatABI::Hard && !IsWindows)
  333. ? "armhf"
  334. : "arm";
  335. // For historic reasons, Android library is using i686 instead of i386.
  336. if (TC.getArch() == llvm::Triple::x86 && Triple.isAndroid())
  337. return "i686";
  338. if (TC.getArch() == llvm::Triple::x86_64 && Triple.isX32())
  339. return "x32";
  340. return llvm::Triple::getArchTypeName(TC.getArch());
  341. }
  342. StringRef ToolChain::getOSLibName() const {
  343. if (Triple.isOSDarwin())
  344. return "darwin";
  345. switch (Triple.getOS()) {
  346. case llvm::Triple::FreeBSD:
  347. return "freebsd";
  348. case llvm::Triple::NetBSD:
  349. return "netbsd";
  350. case llvm::Triple::OpenBSD:
  351. return "openbsd";
  352. case llvm::Triple::Solaris:
  353. return "sunos";
  354. case llvm::Triple::AIX:
  355. return "aix";
  356. default:
  357. return getOS();
  358. }
  359. }
  360. std::string ToolChain::getCompilerRTPath() const {
  361. SmallString<128> Path(getDriver().ResourceDir);
  362. if (Triple.isOSUnknown()) {
  363. llvm::sys::path::append(Path, "lib");
  364. } else {
  365. llvm::sys::path::append(Path, "lib", getOSLibName());
  366. }
  367. return std::string(Path.str());
  368. }
  369. std::string ToolChain::getCompilerRTBasename(const ArgList &Args,
  370. StringRef Component,
  371. FileType Type) const {
  372. std::string CRTAbsolutePath = getCompilerRT(Args, Component, Type);
  373. return llvm::sys::path::filename(CRTAbsolutePath).str();
  374. }
  375. std::string ToolChain::buildCompilerRTBasename(const llvm::opt::ArgList &Args,
  376. StringRef Component,
  377. FileType Type,
  378. bool AddArch) const {
  379. const llvm::Triple &TT = getTriple();
  380. bool IsITANMSVCWindows =
  381. TT.isWindowsMSVCEnvironment() || TT.isWindowsItaniumEnvironment();
  382. const char *Prefix =
  383. IsITANMSVCWindows || Type == ToolChain::FT_Object ? "" : "lib";
  384. const char *Suffix;
  385. switch (Type) {
  386. case ToolChain::FT_Object:
  387. Suffix = IsITANMSVCWindows ? ".obj" : ".o";
  388. break;
  389. case ToolChain::FT_Static:
  390. Suffix = IsITANMSVCWindows ? ".lib" : ".a";
  391. break;
  392. case ToolChain::FT_Shared:
  393. Suffix = TT.isOSWindows()
  394. ? (TT.isWindowsGNUEnvironment() ? ".dll.a" : ".lib")
  395. : ".so";
  396. break;
  397. }
  398. std::string ArchAndEnv;
  399. if (AddArch) {
  400. StringRef Arch = getArchNameForCompilerRTLib(*this, Args);
  401. const char *Env = TT.isAndroid() ? "-android" : "";
  402. ArchAndEnv = ("-" + Arch + Env).str();
  403. }
  404. return (Prefix + Twine("clang_rt.") + Component + ArchAndEnv + Suffix).str();
  405. }
  406. std::string ToolChain::getCompilerRT(const ArgList &Args, StringRef Component,
  407. FileType Type) const {
  408. // Check for runtime files in the new layout without the architecture first.
  409. std::string CRTBasename =
  410. buildCompilerRTBasename(Args, Component, Type, /*AddArch=*/false);
  411. for (const auto &LibPath : getLibraryPaths()) {
  412. SmallString<128> P(LibPath);
  413. llvm::sys::path::append(P, CRTBasename);
  414. if (getVFS().exists(P))
  415. return std::string(P.str());
  416. }
  417. // Fall back to the old expected compiler-rt name if the new one does not
  418. // exist.
  419. CRTBasename =
  420. buildCompilerRTBasename(Args, Component, Type, /*AddArch=*/true);
  421. SmallString<128> Path(getCompilerRTPath());
  422. llvm::sys::path::append(Path, CRTBasename);
  423. return std::string(Path.str());
  424. }
  425. const char *ToolChain::getCompilerRTArgString(const llvm::opt::ArgList &Args,
  426. StringRef Component,
  427. FileType Type) const {
  428. return Args.MakeArgString(getCompilerRT(Args, Component, Type));
  429. }
  430. ToolChain::path_list ToolChain::getRuntimePaths() const {
  431. path_list Paths;
  432. auto addPathForTriple = [this, &Paths](const llvm::Triple &Triple) {
  433. SmallString<128> P(D.ResourceDir);
  434. llvm::sys::path::append(P, "lib", Triple.str());
  435. Paths.push_back(std::string(P.str()));
  436. };
  437. addPathForTriple(getTriple());
  438. // Android targets may include an API level at the end. We still want to fall
  439. // back on a path without the API level.
  440. if (getTriple().isAndroid() &&
  441. getTriple().getEnvironmentName() != "android") {
  442. llvm::Triple TripleWithoutLevel = getTriple();
  443. TripleWithoutLevel.setEnvironmentName("android");
  444. addPathForTriple(TripleWithoutLevel);
  445. }
  446. return Paths;
  447. }
  448. ToolChain::path_list ToolChain::getStdlibPaths() const {
  449. path_list Paths;
  450. SmallString<128> P(D.Dir);
  451. llvm::sys::path::append(P, "..", "lib", getTripleString());
  452. Paths.push_back(std::string(P.str()));
  453. return Paths;
  454. }
  455. std::string ToolChain::getArchSpecificLibPath() const {
  456. SmallString<128> Path(getDriver().ResourceDir);
  457. llvm::sys::path::append(Path, "lib", getOSLibName(),
  458. llvm::Triple::getArchTypeName(getArch()));
  459. return std::string(Path.str());
  460. }
  461. bool ToolChain::needsProfileRT(const ArgList &Args) {
  462. if (Args.hasArg(options::OPT_noprofilelib))
  463. return false;
  464. return Args.hasArg(options::OPT_fprofile_generate) ||
  465. Args.hasArg(options::OPT_fprofile_generate_EQ) ||
  466. Args.hasArg(options::OPT_fcs_profile_generate) ||
  467. Args.hasArg(options::OPT_fcs_profile_generate_EQ) ||
  468. Args.hasArg(options::OPT_fprofile_instr_generate) ||
  469. Args.hasArg(options::OPT_fprofile_instr_generate_EQ) ||
  470. Args.hasArg(options::OPT_fcreate_profile) ||
  471. Args.hasArg(options::OPT_forder_file_instrumentation);
  472. }
  473. bool ToolChain::needsGCovInstrumentation(const llvm::opt::ArgList &Args) {
  474. return Args.hasArg(options::OPT_coverage) ||
  475. Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs,
  476. false);
  477. }
  478. Tool *ToolChain::SelectTool(const JobAction &JA) const {
  479. if (D.IsFlangMode() && getDriver().ShouldUseFlangCompiler(JA)) return getFlang();
  480. if (getDriver().ShouldUseClangCompiler(JA)) return getClang();
  481. Action::ActionClass AC = JA.getKind();
  482. if (AC == Action::AssembleJobClass && useIntegratedAs())
  483. return getClangAs();
  484. return getTool(AC);
  485. }
  486. std::string ToolChain::GetFilePath(const char *Name) const {
  487. return D.GetFilePath(Name, *this);
  488. }
  489. std::string ToolChain::GetProgramPath(const char *Name) const {
  490. return D.GetProgramPath(Name, *this);
  491. }
  492. std::string ToolChain::GetLinkerPath(bool *LinkerIsLLD) const {
  493. if (LinkerIsLLD)
  494. *LinkerIsLLD = false;
  495. // Get -fuse-ld= first to prevent -Wunused-command-line-argument. -fuse-ld= is
  496. // considered as the linker flavor, e.g. "bfd", "gold", or "lld".
  497. const Arg* A = Args.getLastArg(options::OPT_fuse_ld_EQ);
  498. StringRef UseLinker = A ? A->getValue() : CLANG_DEFAULT_LINKER;
  499. // --ld-path= takes precedence over -fuse-ld= and specifies the executable
  500. // name. -B, COMPILER_PATH and PATH and consulted if the value does not
  501. // contain a path component separator.
  502. if (const Arg *A = Args.getLastArg(options::OPT_ld_path_EQ)) {
  503. std::string Path(A->getValue());
  504. if (!Path.empty()) {
  505. if (llvm::sys::path::parent_path(Path).empty())
  506. Path = GetProgramPath(A->getValue());
  507. if (llvm::sys::fs::can_execute(Path))
  508. return std::string(Path);
  509. }
  510. getDriver().Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args);
  511. return GetProgramPath(getDefaultLinker());
  512. }
  513. // If we're passed -fuse-ld= with no argument, or with the argument ld,
  514. // then use whatever the default system linker is.
  515. if (UseLinker.empty() || UseLinker == "ld") {
  516. const char *DefaultLinker = getDefaultLinker();
  517. if (llvm::sys::path::is_absolute(DefaultLinker))
  518. return std::string(DefaultLinker);
  519. else
  520. return GetProgramPath(DefaultLinker);
  521. }
  522. // Extending -fuse-ld= to an absolute or relative path is unexpected. Checking
  523. // for the linker flavor is brittle. In addition, prepending "ld." or "ld64."
  524. // to a relative path is surprising. This is more complex due to priorities
  525. // among -B, COMPILER_PATH and PATH. --ld-path= should be used instead.
  526. if (UseLinker.contains('/'))
  527. getDriver().Diag(diag::warn_drv_fuse_ld_path);
  528. if (llvm::sys::path::is_absolute(UseLinker)) {
  529. // If we're passed what looks like an absolute path, don't attempt to
  530. // second-guess that.
  531. if (llvm::sys::fs::can_execute(UseLinker))
  532. return std::string(UseLinker);
  533. } else {
  534. llvm::SmallString<8> LinkerName;
  535. if (Triple.isOSDarwin())
  536. LinkerName.append("ld64.");
  537. else
  538. LinkerName.append("ld.");
  539. LinkerName.append(UseLinker);
  540. std::string LinkerPath(GetProgramPath(LinkerName.c_str()));
  541. if (llvm::sys::fs::can_execute(LinkerPath)) {
  542. if (LinkerIsLLD)
  543. *LinkerIsLLD = UseLinker == "lld";
  544. return LinkerPath;
  545. }
  546. }
  547. if (A)
  548. getDriver().Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args);
  549. return GetProgramPath(getDefaultLinker());
  550. }
  551. std::string ToolChain::GetStaticLibToolPath() const {
  552. // TODO: Add support for static lib archiving on Windows
  553. if (Triple.isOSDarwin())
  554. return GetProgramPath("libtool");
  555. return GetProgramPath("llvm-ar");
  556. }
  557. types::ID ToolChain::LookupTypeForExtension(StringRef Ext) const {
  558. types::ID id = types::lookupTypeForExtension(Ext);
  559. // Flang always runs the preprocessor and has no notion of "preprocessed
  560. // fortran". Here, TY_PP_Fortran is coerced to TY_Fortran to avoid treating
  561. // them differently.
  562. if (D.IsFlangMode() && id == types::TY_PP_Fortran)
  563. id = types::TY_Fortran;
  564. return id;
  565. }
  566. bool ToolChain::HasNativeLLVMSupport() const {
  567. return false;
  568. }
  569. bool ToolChain::isCrossCompiling() const {
  570. llvm::Triple HostTriple(LLVM_HOST_TRIPLE);
  571. switch (HostTriple.getArch()) {
  572. // The A32/T32/T16 instruction sets are not separate architectures in this
  573. // context.
  574. case llvm::Triple::arm:
  575. case llvm::Triple::armeb:
  576. case llvm::Triple::thumb:
  577. case llvm::Triple::thumbeb:
  578. return getArch() != llvm::Triple::arm && getArch() != llvm::Triple::thumb &&
  579. getArch() != llvm::Triple::armeb && getArch() != llvm::Triple::thumbeb;
  580. default:
  581. return HostTriple.getArch() != getArch();
  582. }
  583. }
  584. ObjCRuntime ToolChain::getDefaultObjCRuntime(bool isNonFragile) const {
  585. return ObjCRuntime(isNonFragile ? ObjCRuntime::GNUstep : ObjCRuntime::GCC,
  586. VersionTuple());
  587. }
  588. llvm::ExceptionHandling
  589. ToolChain::GetExceptionModel(const llvm::opt::ArgList &Args) const {
  590. return llvm::ExceptionHandling::None;
  591. }
  592. bool ToolChain::isThreadModelSupported(const StringRef Model) const {
  593. if (Model == "single") {
  594. // FIXME: 'single' is only supported on ARM and WebAssembly so far.
  595. return Triple.getArch() == llvm::Triple::arm ||
  596. Triple.getArch() == llvm::Triple::armeb ||
  597. Triple.getArch() == llvm::Triple::thumb ||
  598. Triple.getArch() == llvm::Triple::thumbeb || Triple.isWasm();
  599. } else if (Model == "posix")
  600. return true;
  601. return false;
  602. }
  603. std::string ToolChain::ComputeLLVMTriple(const ArgList &Args,
  604. types::ID InputType) const {
  605. switch (getTriple().getArch()) {
  606. default:
  607. return getTripleString();
  608. case llvm::Triple::x86_64: {
  609. llvm::Triple Triple = getTriple();
  610. if (!Triple.isOSBinFormatMachO())
  611. return getTripleString();
  612. if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
  613. // x86_64h goes in the triple. Other -march options just use the
  614. // vanilla triple we already have.
  615. StringRef MArch = A->getValue();
  616. if (MArch == "x86_64h")
  617. Triple.setArchName(MArch);
  618. }
  619. return Triple.getTriple();
  620. }
  621. case llvm::Triple::aarch64: {
  622. llvm::Triple Triple = getTriple();
  623. if (!Triple.isOSBinFormatMachO())
  624. return getTripleString();
  625. if (Triple.isArm64e())
  626. return getTripleString();
  627. // FIXME: older versions of ld64 expect the "arm64" component in the actual
  628. // triple string and query it to determine whether an LTO file can be
  629. // handled. Remove this when we don't care any more.
  630. Triple.setArchName("arm64");
  631. return Triple.getTriple();
  632. }
  633. case llvm::Triple::aarch64_32:
  634. return getTripleString();
  635. case llvm::Triple::arm:
  636. case llvm::Triple::armeb:
  637. case llvm::Triple::thumb:
  638. case llvm::Triple::thumbeb: {
  639. llvm::Triple Triple = getTriple();
  640. tools::arm::setArchNameInTriple(getDriver(), Args, InputType, Triple);
  641. tools::arm::setFloatABIInTriple(getDriver(), Args, Triple);
  642. return Triple.getTriple();
  643. }
  644. }
  645. }
  646. std::string ToolChain::ComputeEffectiveClangTriple(const ArgList &Args,
  647. types::ID InputType) const {
  648. return ComputeLLVMTriple(Args, InputType);
  649. }
  650. std::string ToolChain::computeSysRoot() const {
  651. return D.SysRoot;
  652. }
  653. void ToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
  654. ArgStringList &CC1Args) const {
  655. // Each toolchain should provide the appropriate include flags.
  656. }
  657. void ToolChain::addClangTargetOptions(
  658. const ArgList &DriverArgs, ArgStringList &CC1Args,
  659. Action::OffloadKind DeviceOffloadKind) const {}
  660. void ToolChain::addClangWarningOptions(ArgStringList &CC1Args) const {}
  661. void ToolChain::addProfileRTLibs(const llvm::opt::ArgList &Args,
  662. llvm::opt::ArgStringList &CmdArgs) const {
  663. if (!needsProfileRT(Args) && !needsGCovInstrumentation(Args))
  664. return;
  665. CmdArgs.push_back(getCompilerRTArgString(Args, "profile"));
  666. }
  667. ToolChain::RuntimeLibType ToolChain::GetRuntimeLibType(
  668. const ArgList &Args) const {
  669. if (runtimeLibType)
  670. return *runtimeLibType;
  671. const Arg* A = Args.getLastArg(options::OPT_rtlib_EQ);
  672. StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_RTLIB;
  673. // Only use "platform" in tests to override CLANG_DEFAULT_RTLIB!
  674. if (LibName == "compiler-rt")
  675. runtimeLibType = ToolChain::RLT_CompilerRT;
  676. else if (LibName == "libgcc")
  677. runtimeLibType = ToolChain::RLT_Libgcc;
  678. else if (LibName == "platform")
  679. runtimeLibType = GetDefaultRuntimeLibType();
  680. else {
  681. if (A)
  682. getDriver().Diag(diag::err_drv_invalid_rtlib_name)
  683. << A->getAsString(Args);
  684. runtimeLibType = GetDefaultRuntimeLibType();
  685. }
  686. return *runtimeLibType;
  687. }
  688. ToolChain::UnwindLibType ToolChain::GetUnwindLibType(
  689. const ArgList &Args) const {
  690. if (unwindLibType)
  691. return *unwindLibType;
  692. const Arg *A = Args.getLastArg(options::OPT_unwindlib_EQ);
  693. StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_UNWINDLIB;
  694. if (LibName == "none")
  695. unwindLibType = ToolChain::UNW_None;
  696. else if (LibName == "platform" || LibName == "") {
  697. ToolChain::RuntimeLibType RtLibType = GetRuntimeLibType(Args);
  698. if (RtLibType == ToolChain::RLT_CompilerRT) {
  699. if (getTriple().isAndroid() || getTriple().isOSAIX())
  700. unwindLibType = ToolChain::UNW_CompilerRT;
  701. else
  702. unwindLibType = ToolChain::UNW_None;
  703. } else if (RtLibType == ToolChain::RLT_Libgcc)
  704. unwindLibType = ToolChain::UNW_Libgcc;
  705. } else if (LibName == "libunwind") {
  706. if (GetRuntimeLibType(Args) == RLT_Libgcc)
  707. getDriver().Diag(diag::err_drv_incompatible_unwindlib);
  708. unwindLibType = ToolChain::UNW_CompilerRT;
  709. } else if (LibName == "libgcc")
  710. unwindLibType = ToolChain::UNW_Libgcc;
  711. else {
  712. if (A)
  713. getDriver().Diag(diag::err_drv_invalid_unwindlib_name)
  714. << A->getAsString(Args);
  715. unwindLibType = GetDefaultUnwindLibType();
  716. }
  717. return *unwindLibType;
  718. }
  719. ToolChain::CXXStdlibType ToolChain::GetCXXStdlibType(const ArgList &Args) const{
  720. if (cxxStdlibType)
  721. return *cxxStdlibType;
  722. const Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
  723. StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_CXX_STDLIB;
  724. // Only use "platform" in tests to override CLANG_DEFAULT_CXX_STDLIB!
  725. if (LibName == "libc++")
  726. cxxStdlibType = ToolChain::CST_Libcxx;
  727. else if (LibName == "libstdc++")
  728. cxxStdlibType = ToolChain::CST_Libstdcxx;
  729. else if (LibName == "platform")
  730. cxxStdlibType = GetDefaultCXXStdlibType();
  731. else {
  732. if (A)
  733. getDriver().Diag(diag::err_drv_invalid_stdlib_name)
  734. << A->getAsString(Args);
  735. cxxStdlibType = GetDefaultCXXStdlibType();
  736. }
  737. return *cxxStdlibType;
  738. }
  739. /// Utility function to add a system include directory to CC1 arguments.
  740. /*static*/ void ToolChain::addSystemInclude(const ArgList &DriverArgs,
  741. ArgStringList &CC1Args,
  742. const Twine &Path) {
  743. CC1Args.push_back("-internal-isystem");
  744. CC1Args.push_back(DriverArgs.MakeArgString(Path));
  745. }
  746. /// Utility function to add a system include directory with extern "C"
  747. /// semantics to CC1 arguments.
  748. ///
  749. /// Note that this should be used rarely, and only for directories that
  750. /// historically and for legacy reasons are treated as having implicit extern
  751. /// "C" semantics. These semantics are *ignored* by and large today, but its
  752. /// important to preserve the preprocessor changes resulting from the
  753. /// classification.
  754. /*static*/ void ToolChain::addExternCSystemInclude(const ArgList &DriverArgs,
  755. ArgStringList &CC1Args,
  756. const Twine &Path) {
  757. CC1Args.push_back("-internal-externc-isystem");
  758. CC1Args.push_back(DriverArgs.MakeArgString(Path));
  759. }
  760. void ToolChain::addExternCSystemIncludeIfExists(const ArgList &DriverArgs,
  761. ArgStringList &CC1Args,
  762. const Twine &Path) {
  763. if (llvm::sys::fs::exists(Path))
  764. addExternCSystemInclude(DriverArgs, CC1Args, Path);
  765. }
  766. /// Utility function to add a list of system include directories to CC1.
  767. /*static*/ void ToolChain::addSystemIncludes(const ArgList &DriverArgs,
  768. ArgStringList &CC1Args,
  769. ArrayRef<StringRef> Paths) {
  770. for (const auto &Path : Paths) {
  771. CC1Args.push_back("-internal-isystem");
  772. CC1Args.push_back(DriverArgs.MakeArgString(Path));
  773. }
  774. }
  775. std::string ToolChain::detectLibcxxVersion(StringRef IncludePath) const {
  776. std::error_code EC;
  777. int MaxVersion = 0;
  778. std::string MaxVersionString;
  779. SmallString<128> Path(IncludePath);
  780. llvm::sys::path::append(Path, "c++");
  781. for (llvm::vfs::directory_iterator LI = getVFS().dir_begin(Path, EC), LE;
  782. !EC && LI != LE; LI = LI.increment(EC)) {
  783. StringRef VersionText = llvm::sys::path::filename(LI->path());
  784. int Version;
  785. if (VersionText[0] == 'v' &&
  786. !VersionText.slice(1, StringRef::npos).getAsInteger(10, Version)) {
  787. if (Version > MaxVersion) {
  788. MaxVersion = Version;
  789. MaxVersionString = std::string(VersionText);
  790. }
  791. }
  792. }
  793. if (!MaxVersion)
  794. return "";
  795. return MaxVersionString;
  796. }
  797. void ToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
  798. ArgStringList &CC1Args) const {
  799. // Header search paths should be handled by each of the subclasses.
  800. // Historically, they have not been, and instead have been handled inside of
  801. // the CC1-layer frontend. As the logic is hoisted out, this generic function
  802. // will slowly stop being called.
  803. //
  804. // While it is being called, replicate a bit of a hack to propagate the
  805. // '-stdlib=' flag down to CC1 so that it can in turn customize the C++
  806. // header search paths with it. Once all systems are overriding this
  807. // function, the CC1 flag and this line can be removed.
  808. DriverArgs.AddAllArgs(CC1Args, options::OPT_stdlib_EQ);
  809. }
  810. void ToolChain::AddClangCXXStdlibIsystemArgs(
  811. const llvm::opt::ArgList &DriverArgs,
  812. llvm::opt::ArgStringList &CC1Args) const {
  813. DriverArgs.ClaimAllArgs(options::OPT_stdlibxx_isystem);
  814. if (!DriverArgs.hasArg(options::OPT_nostdinc, options::OPT_nostdincxx,
  815. options::OPT_nostdlibinc))
  816. for (const auto &P :
  817. DriverArgs.getAllArgValues(options::OPT_stdlibxx_isystem))
  818. addSystemInclude(DriverArgs, CC1Args, P);
  819. }
  820. bool ToolChain::ShouldLinkCXXStdlib(const llvm::opt::ArgList &Args) const {
  821. return getDriver().CCCIsCXX() &&
  822. !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs,
  823. options::OPT_nostdlibxx);
  824. }
  825. void ToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
  826. ArgStringList &CmdArgs) const {
  827. assert(!Args.hasArg(options::OPT_nostdlibxx) &&
  828. "should not have called this");
  829. CXXStdlibType Type = GetCXXStdlibType(Args);
  830. switch (Type) {
  831. case ToolChain::CST_Libcxx:
  832. CmdArgs.push_back("-lc++");
  833. break;
  834. case ToolChain::CST_Libstdcxx:
  835. CmdArgs.push_back("-lstdc++");
  836. break;
  837. }
  838. }
  839. void ToolChain::AddFilePathLibArgs(const ArgList &Args,
  840. ArgStringList &CmdArgs) const {
  841. for (const auto &LibPath : getFilePaths())
  842. if(LibPath.length() > 0)
  843. CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + LibPath));
  844. }
  845. void ToolChain::AddCCKextLibArgs(const ArgList &Args,
  846. ArgStringList &CmdArgs) const {
  847. CmdArgs.push_back("-lcc_kext");
  848. }
  849. bool ToolChain::isFastMathRuntimeAvailable(const ArgList &Args,
  850. std::string &Path) const {
  851. // Do not check for -fno-fast-math or -fno-unsafe-math when -Ofast passed
  852. // (to keep the linker options consistent with gcc and clang itself).
  853. if (!isOptimizationLevelFast(Args)) {
  854. // Check if -ffast-math or -funsafe-math.
  855. Arg *A =
  856. Args.getLastArg(options::OPT_ffast_math, options::OPT_fno_fast_math,
  857. options::OPT_funsafe_math_optimizations,
  858. options::OPT_fno_unsafe_math_optimizations);
  859. if (!A || A->getOption().getID() == options::OPT_fno_fast_math ||
  860. A->getOption().getID() == options::OPT_fno_unsafe_math_optimizations)
  861. return false;
  862. }
  863. // If crtfastmath.o exists add it to the arguments.
  864. Path = GetFilePath("crtfastmath.o");
  865. return (Path != "crtfastmath.o"); // Not found.
  866. }
  867. bool ToolChain::addFastMathRuntimeIfAvailable(const ArgList &Args,
  868. ArgStringList &CmdArgs) const {
  869. std::string Path;
  870. if (isFastMathRuntimeAvailable(Args, Path)) {
  871. CmdArgs.push_back(Args.MakeArgString(Path));
  872. return true;
  873. }
  874. return false;
  875. }
  876. SanitizerMask ToolChain::getSupportedSanitizers() const {
  877. // Return sanitizers which don't require runtime support and are not
  878. // platform dependent.
  879. SanitizerMask Res =
  880. (SanitizerKind::Undefined & ~SanitizerKind::Vptr &
  881. ~SanitizerKind::Function) |
  882. (SanitizerKind::CFI & ~SanitizerKind::CFIICall) |
  883. SanitizerKind::CFICastStrict | SanitizerKind::FloatDivideByZero |
  884. SanitizerKind::UnsignedIntegerOverflow |
  885. SanitizerKind::UnsignedShiftBase | SanitizerKind::ImplicitConversion |
  886. SanitizerKind::Nullability | SanitizerKind::LocalBounds;
  887. if (getTriple().getArch() == llvm::Triple::x86 ||
  888. getTriple().getArch() == llvm::Triple::x86_64 ||
  889. getTriple().getArch() == llvm::Triple::arm || getTriple().isWasm() ||
  890. getTriple().isAArch64())
  891. Res |= SanitizerKind::CFIICall;
  892. if (getTriple().getArch() == llvm::Triple::x86_64 ||
  893. getTriple().isAArch64(64) || getTriple().isRISCV())
  894. Res |= SanitizerKind::ShadowCallStack;
  895. if (getTriple().isAArch64(64))
  896. Res |= SanitizerKind::MemTag;
  897. return Res;
  898. }
  899. void ToolChain::AddCudaIncludeArgs(const ArgList &DriverArgs,
  900. ArgStringList &CC1Args) const {}
  901. void ToolChain::AddHIPIncludeArgs(const ArgList &DriverArgs,
  902. ArgStringList &CC1Args) const {}
  903. llvm::SmallVector<ToolChain::BitCodeLibraryInfo, 12>
  904. ToolChain::getHIPDeviceLibs(const ArgList &DriverArgs) const {
  905. return {};
  906. }
  907. void ToolChain::AddIAMCUIncludeArgs(const ArgList &DriverArgs,
  908. ArgStringList &CC1Args) const {}
  909. static VersionTuple separateMSVCFullVersion(unsigned Version) {
  910. if (Version < 100)
  911. return VersionTuple(Version);
  912. if (Version < 10000)
  913. return VersionTuple(Version / 100, Version % 100);
  914. unsigned Build = 0, Factor = 1;
  915. for (; Version > 10000; Version = Version / 10, Factor = Factor * 10)
  916. Build = Build + (Version % 10) * Factor;
  917. return VersionTuple(Version / 100, Version % 100, Build);
  918. }
  919. VersionTuple
  920. ToolChain::computeMSVCVersion(const Driver *D,
  921. const llvm::opt::ArgList &Args) const {
  922. const Arg *MSCVersion = Args.getLastArg(options::OPT_fmsc_version);
  923. const Arg *MSCompatibilityVersion =
  924. Args.getLastArg(options::OPT_fms_compatibility_version);
  925. if (MSCVersion && MSCompatibilityVersion) {
  926. if (D)
  927. D->Diag(diag::err_drv_argument_not_allowed_with)
  928. << MSCVersion->getAsString(Args)
  929. << MSCompatibilityVersion->getAsString(Args);
  930. return VersionTuple();
  931. }
  932. if (MSCompatibilityVersion) {
  933. VersionTuple MSVT;
  934. if (MSVT.tryParse(MSCompatibilityVersion->getValue())) {
  935. if (D)
  936. D->Diag(diag::err_drv_invalid_value)
  937. << MSCompatibilityVersion->getAsString(Args)
  938. << MSCompatibilityVersion->getValue();
  939. } else {
  940. return MSVT;
  941. }
  942. }
  943. if (MSCVersion) {
  944. unsigned Version = 0;
  945. if (StringRef(MSCVersion->getValue()).getAsInteger(10, Version)) {
  946. if (D)
  947. D->Diag(diag::err_drv_invalid_value)
  948. << MSCVersion->getAsString(Args) << MSCVersion->getValue();
  949. } else {
  950. return separateMSVCFullVersion(Version);
  951. }
  952. }
  953. return VersionTuple();
  954. }
  955. llvm::opt::DerivedArgList *ToolChain::TranslateOpenMPTargetArgs(
  956. const llvm::opt::DerivedArgList &Args, bool SameTripleAsHost,
  957. SmallVectorImpl<llvm::opt::Arg *> &AllocatedArgs) const {
  958. DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
  959. const OptTable &Opts = getDriver().getOpts();
  960. bool Modified = false;
  961. // Handle -Xopenmp-target flags
  962. for (auto *A : Args) {
  963. // Exclude flags which may only apply to the host toolchain.
  964. // Do not exclude flags when the host triple (AuxTriple)
  965. // matches the current toolchain triple. If it is not present
  966. // at all, target and host share a toolchain.
  967. if (A->getOption().matches(options::OPT_m_Group)) {
  968. if (SameTripleAsHost)
  969. DAL->append(A);
  970. else
  971. Modified = true;
  972. continue;
  973. }
  974. unsigned Index;
  975. unsigned Prev;
  976. bool XOpenMPTargetNoTriple =
  977. A->getOption().matches(options::OPT_Xopenmp_target);
  978. if (A->getOption().matches(options::OPT_Xopenmp_target_EQ)) {
  979. llvm::Triple TT(getOpenMPTriple(A->getValue(0)));
  980. // Passing device args: -Xopenmp-target=<triple> -opt=val.
  981. if (TT.getTriple() == getTripleString())
  982. Index = Args.getBaseArgs().MakeIndex(A->getValue(1));
  983. else
  984. continue;
  985. } else if (XOpenMPTargetNoTriple) {
  986. // Passing device args: -Xopenmp-target -opt=val.
  987. Index = Args.getBaseArgs().MakeIndex(A->getValue(0));
  988. } else {
  989. DAL->append(A);
  990. continue;
  991. }
  992. // Parse the argument to -Xopenmp-target.
  993. Prev = Index;
  994. std::unique_ptr<Arg> XOpenMPTargetArg(Opts.ParseOneArg(Args, Index));
  995. if (!XOpenMPTargetArg || Index > Prev + 1) {
  996. getDriver().Diag(diag::err_drv_invalid_Xopenmp_target_with_args)
  997. << A->getAsString(Args);
  998. continue;
  999. }
  1000. if (XOpenMPTargetNoTriple && XOpenMPTargetArg &&
  1001. Args.getAllArgValues(options::OPT_fopenmp_targets_EQ).size() != 1) {
  1002. getDriver().Diag(diag::err_drv_Xopenmp_target_missing_triple);
  1003. continue;
  1004. }
  1005. XOpenMPTargetArg->setBaseArg(A);
  1006. A = XOpenMPTargetArg.release();
  1007. AllocatedArgs.push_back(A);
  1008. DAL->append(A);
  1009. Modified = true;
  1010. }
  1011. if (Modified)
  1012. return DAL;
  1013. delete DAL;
  1014. return nullptr;
  1015. }
  1016. // TODO: Currently argument values separated by space e.g.
  1017. // -Xclang -mframe-pointer=no cannot be passed by -Xarch_. This should be
  1018. // fixed.
  1019. void ToolChain::TranslateXarchArgs(
  1020. const llvm::opt::DerivedArgList &Args, llvm::opt::Arg *&A,
  1021. llvm::opt::DerivedArgList *DAL,
  1022. SmallVectorImpl<llvm::opt::Arg *> *AllocatedArgs) const {
  1023. const OptTable &Opts = getDriver().getOpts();
  1024. unsigned ValuePos = 1;
  1025. if (A->getOption().matches(options::OPT_Xarch_device) ||
  1026. A->getOption().matches(options::OPT_Xarch_host))
  1027. ValuePos = 0;
  1028. unsigned Index = Args.getBaseArgs().MakeIndex(A->getValue(ValuePos));
  1029. unsigned Prev = Index;
  1030. std::unique_ptr<llvm::opt::Arg> XarchArg(Opts.ParseOneArg(Args, Index));
  1031. // If the argument parsing failed or more than one argument was
  1032. // consumed, the -Xarch_ argument's parameter tried to consume
  1033. // extra arguments. Emit an error and ignore.
  1034. //
  1035. // We also want to disallow any options which would alter the
  1036. // driver behavior; that isn't going to work in our model. We
  1037. // use options::NoXarchOption to control this.
  1038. if (!XarchArg || Index > Prev + 1) {
  1039. getDriver().Diag(diag::err_drv_invalid_Xarch_argument_with_args)
  1040. << A->getAsString(Args);
  1041. return;
  1042. } else if (XarchArg->getOption().hasFlag(options::NoXarchOption)) {
  1043. auto &Diags = getDriver().getDiags();
  1044. unsigned DiagID =
  1045. Diags.getCustomDiagID(DiagnosticsEngine::Error,
  1046. "invalid Xarch argument: '%0', not all driver "
  1047. "options can be forwared via Xarch argument");
  1048. Diags.Report(DiagID) << A->getAsString(Args);
  1049. return;
  1050. }
  1051. XarchArg->setBaseArg(A);
  1052. A = XarchArg.release();
  1053. if (!AllocatedArgs)
  1054. DAL->AddSynthesizedArg(A);
  1055. else
  1056. AllocatedArgs->push_back(A);
  1057. }
  1058. llvm::opt::DerivedArgList *ToolChain::TranslateXarchArgs(
  1059. const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
  1060. Action::OffloadKind OFK,
  1061. SmallVectorImpl<llvm::opt::Arg *> *AllocatedArgs) const {
  1062. DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
  1063. bool Modified = false;
  1064. bool IsGPU = OFK == Action::OFK_Cuda || OFK == Action::OFK_HIP;
  1065. for (Arg *A : Args) {
  1066. bool NeedTrans = false;
  1067. bool Skip = false;
  1068. if (A->getOption().matches(options::OPT_Xarch_device)) {
  1069. NeedTrans = IsGPU;
  1070. Skip = !IsGPU;
  1071. } else if (A->getOption().matches(options::OPT_Xarch_host)) {
  1072. NeedTrans = !IsGPU;
  1073. Skip = IsGPU;
  1074. } else if (A->getOption().matches(options::OPT_Xarch__) && IsGPU) {
  1075. // Do not translate -Xarch_ options for non CUDA/HIP toolchain since
  1076. // they may need special translation.
  1077. // Skip this argument unless the architecture matches BoundArch
  1078. if (BoundArch.empty() || A->getValue(0) != BoundArch)
  1079. Skip = true;
  1080. else
  1081. NeedTrans = true;
  1082. }
  1083. if (NeedTrans || Skip)
  1084. Modified = true;
  1085. if (NeedTrans)
  1086. TranslateXarchArgs(Args, A, DAL, AllocatedArgs);
  1087. if (!Skip)
  1088. DAL->append(A);
  1089. }
  1090. if (Modified)
  1091. return DAL;
  1092. delete DAL;
  1093. return nullptr;
  1094. }