ToolChain.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632
  1. //===--- ToolChain.cpp - Collections of tools for one platform ------------===//
  2. //
  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. #include "Tools.h"
  10. #include "clang/Basic/ObjCRuntime.h"
  11. #include "clang/Driver/Action.h"
  12. #include "clang/Driver/Driver.h"
  13. #include "clang/Driver/DriverDiagnostic.h"
  14. #include "clang/Driver/Options.h"
  15. #include "clang/Driver/SanitizerArgs.h"
  16. #include "clang/Driver/ToolChain.h"
  17. #include "llvm/ADT/SmallString.h"
  18. #include "llvm/ADT/StringSwitch.h"
  19. #include "llvm/Option/Arg.h"
  20. #include "llvm/Option/ArgList.h"
  21. #include "llvm/Option/Option.h"
  22. #include "llvm/Support/ErrorHandling.h"
  23. #include "llvm/Support/FileSystem.h"
  24. #include "llvm/Support/TargetRegistry.h"
  25. using namespace clang::driver;
  26. using namespace clang::driver::tools;
  27. using namespace clang;
  28. using namespace llvm::opt;
  29. static llvm::opt::Arg *GetRTTIArgument(const ArgList &Args) {
  30. return Args.getLastArg(options::OPT_mkernel, options::OPT_fapple_kext,
  31. options::OPT_fno_rtti, options::OPT_frtti);
  32. }
  33. static ToolChain::RTTIMode CalculateRTTIMode(const ArgList &Args,
  34. const llvm::Triple &Triple,
  35. const Arg *CachedRTTIArg) {
  36. // Explicit rtti/no-rtti args
  37. if (CachedRTTIArg) {
  38. if (CachedRTTIArg->getOption().matches(options::OPT_frtti))
  39. return ToolChain::RM_EnabledExplicitly;
  40. else
  41. return ToolChain::RM_DisabledExplicitly;
  42. }
  43. // -frtti is default, except for the PS4 CPU.
  44. if (!Triple.isPS4CPU())
  45. return ToolChain::RM_EnabledImplicitly;
  46. // On the PS4, turning on c++ exceptions turns on rtti.
  47. // We're assuming that, if we see -fexceptions, rtti gets turned on.
  48. Arg *Exceptions = Args.getLastArgNoClaim(
  49. options::OPT_fcxx_exceptions, options::OPT_fno_cxx_exceptions,
  50. options::OPT_fexceptions, options::OPT_fno_exceptions);
  51. if (Exceptions &&
  52. (Exceptions->getOption().matches(options::OPT_fexceptions) ||
  53. Exceptions->getOption().matches(options::OPT_fcxx_exceptions)))
  54. return ToolChain::RM_EnabledImplicitly;
  55. return ToolChain::RM_DisabledImplicitly;
  56. }
  57. ToolChain::ToolChain(const Driver &D, const llvm::Triple &T,
  58. const ArgList &Args)
  59. : D(D), Triple(T), Args(Args), CachedRTTIArg(GetRTTIArgument(Args)),
  60. CachedRTTIMode(CalculateRTTIMode(Args, Triple, CachedRTTIArg)) {
  61. if (Arg *A = Args.getLastArg(options::OPT_mthread_model))
  62. if (!isThreadModelSupported(A->getValue()))
  63. D.Diag(diag::err_drv_invalid_thread_model_for_target)
  64. << A->getValue() << A->getAsString(Args);
  65. }
  66. ToolChain::~ToolChain() {
  67. }
  68. vfs::FileSystem &ToolChain::getVFS() const { return getDriver().getVFS(); }
  69. bool ToolChain::useIntegratedAs() const {
  70. return Args.hasFlag(options::OPT_fintegrated_as,
  71. options::OPT_fno_integrated_as,
  72. IsIntegratedAssemblerDefault());
  73. }
  74. const SanitizerArgs& ToolChain::getSanitizerArgs() const {
  75. if (!SanitizerArguments.get())
  76. SanitizerArguments.reset(new SanitizerArgs(*this, Args));
  77. return *SanitizerArguments.get();
  78. }
  79. namespace {
  80. struct DriverSuffix {
  81. const char *Suffix;
  82. const char *ModeFlag;
  83. };
  84. const DriverSuffix *FindDriverSuffix(StringRef ProgName) {
  85. // A list of known driver suffixes. Suffixes are compared against the
  86. // program name in order. If there is a match, the frontend type is updated as
  87. // necessary by applying the ModeFlag.
  88. static const DriverSuffix DriverSuffixes[] = {
  89. {"clang", nullptr},
  90. {"clang++", "--driver-mode=g++"},
  91. {"clang-c++", "--driver-mode=g++"},
  92. {"clang-cc", nullptr},
  93. {"clang-cpp", "--driver-mode=cpp"},
  94. {"clang-g++", "--driver-mode=g++"},
  95. {"clang-gcc", nullptr},
  96. {"clang-cl", "--driver-mode=cl"},
  97. {"cc", nullptr},
  98. {"cpp", "--driver-mode=cpp"},
  99. {"cl", "--driver-mode=cl"},
  100. {"++", "--driver-mode=g++"},
  101. };
  102. for (size_t i = 0; i < llvm::array_lengthof(DriverSuffixes); ++i)
  103. if (ProgName.endswith(DriverSuffixes[i].Suffix))
  104. return &DriverSuffixes[i];
  105. return nullptr;
  106. }
  107. /// Normalize the program name from argv[0] by stripping the file extension if
  108. /// present and lower-casing the string on Windows.
  109. std::string normalizeProgramName(llvm::StringRef Argv0) {
  110. std::string ProgName = llvm::sys::path::stem(Argv0);
  111. #ifdef LLVM_ON_WIN32
  112. // Transform to lowercase for case insensitive file systems.
  113. std::transform(ProgName.begin(), ProgName.end(), ProgName.begin(), ::tolower);
  114. #endif
  115. return ProgName;
  116. }
  117. const DriverSuffix *parseDriverSuffix(StringRef ProgName) {
  118. // Try to infer frontend type and default target from the program name by
  119. // comparing it against DriverSuffixes in order.
  120. // If there is a match, the function tries to identify a target as prefix.
  121. // E.g. "x86_64-linux-clang" as interpreted as suffix "clang" with target
  122. // prefix "x86_64-linux". If such a target prefix is found, it may be
  123. // added via -target as implicit first argument.
  124. const DriverSuffix *DS = FindDriverSuffix(ProgName);
  125. if (!DS) {
  126. // Try again after stripping any trailing version number:
  127. // clang++3.5 -> clang++
  128. ProgName = ProgName.rtrim("0123456789.");
  129. DS = FindDriverSuffix(ProgName);
  130. }
  131. if (!DS) {
  132. // Try again after stripping trailing -component.
  133. // clang++-tot -> clang++
  134. ProgName = ProgName.slice(0, ProgName.rfind('-'));
  135. DS = FindDriverSuffix(ProgName);
  136. }
  137. return DS;
  138. }
  139. } // anonymous namespace
  140. std::pair<std::string, std::string>
  141. ToolChain::getTargetAndModeFromProgramName(StringRef PN) {
  142. std::string ProgName = normalizeProgramName(PN);
  143. const DriverSuffix *DS = parseDriverSuffix(ProgName);
  144. if (!DS)
  145. return std::make_pair("", "");
  146. std::string ModeFlag = DS->ModeFlag == nullptr ? "" : DS->ModeFlag;
  147. std::string::size_type LastComponent =
  148. ProgName.rfind('-', ProgName.size() - strlen(DS->Suffix));
  149. if (LastComponent == std::string::npos)
  150. return std::make_pair("", ModeFlag);
  151. // Infer target from the prefix.
  152. StringRef Prefix(ProgName);
  153. Prefix = Prefix.slice(0, LastComponent);
  154. std::string IgnoredError;
  155. std::string Target;
  156. if (llvm::TargetRegistry::lookupTarget(Prefix, IgnoredError)) {
  157. Target = Prefix;
  158. }
  159. return std::make_pair(Target, ModeFlag);
  160. }
  161. StringRef ToolChain::getDefaultUniversalArchName() const {
  162. // In universal driver terms, the arch name accepted by -arch isn't exactly
  163. // the same as the ones that appear in the triple. Roughly speaking, this is
  164. // an inverse of the darwin::getArchTypeForDarwinArchName() function, but the
  165. // only interesting special case is powerpc.
  166. switch (Triple.getArch()) {
  167. case llvm::Triple::ppc:
  168. return "ppc";
  169. case llvm::Triple::ppc64:
  170. return "ppc64";
  171. case llvm::Triple::ppc64le:
  172. return "ppc64le";
  173. default:
  174. return Triple.getArchName();
  175. }
  176. }
  177. bool ToolChain::IsUnwindTablesDefault() const {
  178. return false;
  179. }
  180. Tool *ToolChain::getClang() const {
  181. if (!Clang)
  182. Clang.reset(new tools::Clang(*this));
  183. return Clang.get();
  184. }
  185. Tool *ToolChain::buildAssembler() const {
  186. return new tools::ClangAs(*this);
  187. }
  188. Tool *ToolChain::buildLinker() const {
  189. llvm_unreachable("Linking is not supported by this toolchain");
  190. }
  191. Tool *ToolChain::getAssemble() const {
  192. if (!Assemble)
  193. Assemble.reset(buildAssembler());
  194. return Assemble.get();
  195. }
  196. Tool *ToolChain::getClangAs() const {
  197. if (!Assemble)
  198. Assemble.reset(new tools::ClangAs(*this));
  199. return Assemble.get();
  200. }
  201. Tool *ToolChain::getLink() const {
  202. if (!Link)
  203. Link.reset(buildLinker());
  204. return Link.get();
  205. }
  206. Tool *ToolChain::getTool(Action::ActionClass AC) const {
  207. switch (AC) {
  208. case Action::AssembleJobClass:
  209. return getAssemble();
  210. case Action::LinkJobClass:
  211. return getLink();
  212. case Action::InputClass:
  213. case Action::BindArchClass:
  214. case Action::CudaDeviceClass:
  215. case Action::CudaHostClass:
  216. case Action::LipoJobClass:
  217. case Action::DsymutilJobClass:
  218. case Action::VerifyDebugInfoJobClass:
  219. llvm_unreachable("Invalid tool kind.");
  220. case Action::CompileJobClass:
  221. case Action::PrecompileJobClass:
  222. case Action::PreprocessJobClass:
  223. case Action::AnalyzeJobClass:
  224. case Action::MigrateJobClass:
  225. case Action::VerifyPCHJobClass:
  226. case Action::BackendJobClass:
  227. return getClang();
  228. }
  229. llvm_unreachable("Invalid tool kind.");
  230. }
  231. static StringRef getArchNameForCompilerRTLib(const ToolChain &TC,
  232. const ArgList &Args) {
  233. const llvm::Triple &Triple = TC.getTriple();
  234. bool IsWindows = Triple.isOSWindows();
  235. if (Triple.isWindowsMSVCEnvironment() && TC.getArch() == llvm::Triple::x86)
  236. return "i386";
  237. if (TC.getArch() == llvm::Triple::arm || TC.getArch() == llvm::Triple::armeb)
  238. return (arm::getARMFloatABI(TC, Args) == arm::FloatABI::Hard && !IsWindows)
  239. ? "armhf"
  240. : "arm";
  241. return TC.getArchName();
  242. }
  243. std::string ToolChain::getCompilerRT(const ArgList &Args, StringRef Component,
  244. bool Shared) const {
  245. const llvm::Triple &TT = getTriple();
  246. const char *Env = TT.isAndroid() ? "-android" : "";
  247. bool IsITANMSVCWindows =
  248. TT.isWindowsMSVCEnvironment() || TT.isWindowsItaniumEnvironment();
  249. StringRef Arch = getArchNameForCompilerRTLib(*this, Args);
  250. const char *Prefix = IsITANMSVCWindows ? "" : "lib";
  251. const char *Suffix = Shared ? (Triple.isOSWindows() ? ".dll" : ".so")
  252. : (IsITANMSVCWindows ? ".lib" : ".a");
  253. SmallString<128> Path(getDriver().ResourceDir);
  254. StringRef OSLibName = Triple.isOSFreeBSD() ? "freebsd" : getOS();
  255. llvm::sys::path::append(Path, "lib", OSLibName);
  256. llvm::sys::path::append(Path, Prefix + Twine("clang_rt.") + Component + "-" +
  257. Arch + Env + Suffix);
  258. return Path.str();
  259. }
  260. Tool *ToolChain::SelectTool(const JobAction &JA) const {
  261. if (getDriver().ShouldUseClangCompiler(JA))
  262. return getClang();
  263. Action::ActionClass AC = JA.getKind();
  264. if (AC == Action::AssembleJobClass && useIntegratedAs())
  265. return getClangAs();
  266. return getTool(AC);
  267. }
  268. std::string ToolChain::GetFilePath(const char *Name) const {
  269. return D.GetFilePath(Name, *this);
  270. }
  271. std::string ToolChain::GetProgramPath(const char *Name) const {
  272. return D.GetProgramPath(Name, *this);
  273. }
  274. std::string ToolChain::GetLinkerPath() const {
  275. if (Arg *A = Args.getLastArg(options::OPT_fuse_ld_EQ)) {
  276. StringRef Suffix = A->getValue();
  277. // If we're passed -fuse-ld= with no argument, or with the argument ld,
  278. // then use whatever the default system linker is.
  279. if (Suffix.empty() || Suffix == "ld")
  280. return GetProgramPath("ld");
  281. llvm::SmallString<8> LinkerName("ld.");
  282. LinkerName.append(Suffix);
  283. std::string LinkerPath(GetProgramPath(LinkerName.c_str()));
  284. if (llvm::sys::fs::exists(LinkerPath))
  285. return LinkerPath;
  286. getDriver().Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args);
  287. return "";
  288. }
  289. return GetProgramPath("ld");
  290. }
  291. types::ID ToolChain::LookupTypeForExtension(const char *Ext) const {
  292. return types::lookupTypeForExtension(Ext);
  293. }
  294. bool ToolChain::HasNativeLLVMSupport() const {
  295. return false;
  296. }
  297. bool ToolChain::isCrossCompiling() const {
  298. llvm::Triple HostTriple(LLVM_HOST_TRIPLE);
  299. switch (HostTriple.getArch()) {
  300. // The A32/T32/T16 instruction sets are not separate architectures in this
  301. // context.
  302. case llvm::Triple::arm:
  303. case llvm::Triple::armeb:
  304. case llvm::Triple::thumb:
  305. case llvm::Triple::thumbeb:
  306. return getArch() != llvm::Triple::arm && getArch() != llvm::Triple::thumb &&
  307. getArch() != llvm::Triple::armeb && getArch() != llvm::Triple::thumbeb;
  308. default:
  309. return HostTriple.getArch() != getArch();
  310. }
  311. }
  312. ObjCRuntime ToolChain::getDefaultObjCRuntime(bool isNonFragile) const {
  313. return ObjCRuntime(isNonFragile ? ObjCRuntime::GNUstep : ObjCRuntime::GCC,
  314. VersionTuple());
  315. }
  316. bool ToolChain::isThreadModelSupported(const StringRef Model) const {
  317. if (Model == "single") {
  318. // FIXME: 'single' is only supported on ARM and WebAssembly so far.
  319. return Triple.getArch() == llvm::Triple::arm ||
  320. Triple.getArch() == llvm::Triple::armeb ||
  321. Triple.getArch() == llvm::Triple::thumb ||
  322. Triple.getArch() == llvm::Triple::thumbeb ||
  323. Triple.getArch() == llvm::Triple::wasm32 ||
  324. Triple.getArch() == llvm::Triple::wasm64;
  325. } else if (Model == "posix")
  326. return true;
  327. return false;
  328. }
  329. std::string ToolChain::ComputeLLVMTriple(const ArgList &Args,
  330. types::ID InputType) const {
  331. switch (getTriple().getArch()) {
  332. default:
  333. return getTripleString();
  334. case llvm::Triple::x86_64: {
  335. llvm::Triple Triple = getTriple();
  336. if (!Triple.isOSBinFormatMachO())
  337. return getTripleString();
  338. if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
  339. // x86_64h goes in the triple. Other -march options just use the
  340. // vanilla triple we already have.
  341. StringRef MArch = A->getValue();
  342. if (MArch == "x86_64h")
  343. Triple.setArchName(MArch);
  344. }
  345. return Triple.getTriple();
  346. }
  347. case llvm::Triple::aarch64: {
  348. llvm::Triple Triple = getTriple();
  349. if (!Triple.isOSBinFormatMachO())
  350. return getTripleString();
  351. // FIXME: older versions of ld64 expect the "arm64" component in the actual
  352. // triple string and query it to determine whether an LTO file can be
  353. // handled. Remove this when we don't care any more.
  354. Triple.setArchName("arm64");
  355. return Triple.getTriple();
  356. }
  357. case llvm::Triple::arm:
  358. case llvm::Triple::armeb:
  359. case llvm::Triple::thumb:
  360. case llvm::Triple::thumbeb: {
  361. // FIXME: Factor into subclasses.
  362. llvm::Triple Triple = getTriple();
  363. bool IsBigEndian = getTriple().getArch() == llvm::Triple::armeb ||
  364. getTriple().getArch() == llvm::Triple::thumbeb;
  365. // Handle pseudo-target flags '-mlittle-endian'/'-EL' and
  366. // '-mbig-endian'/'-EB'.
  367. if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian,
  368. options::OPT_mbig_endian)) {
  369. IsBigEndian = !A->getOption().matches(options::OPT_mlittle_endian);
  370. }
  371. // Thumb2 is the default for V7 on Darwin.
  372. //
  373. // FIXME: Thumb should just be another -target-feaure, not in the triple.
  374. StringRef MCPU, MArch;
  375. if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
  376. MCPU = A->getValue();
  377. if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
  378. MArch = A->getValue();
  379. std::string CPU =
  380. Triple.isOSBinFormatMachO()
  381. ? tools::arm::getARMCPUForMArch(MArch, Triple).str()
  382. : tools::arm::getARMTargetCPU(MCPU, MArch, Triple);
  383. StringRef Suffix =
  384. tools::arm::getLLVMArchSuffixForARM(CPU, MArch, Triple);
  385. bool ThumbDefault = Suffix.startswith("v6m") || Suffix.startswith("v7m") ||
  386. Suffix.startswith("v7em") ||
  387. (Suffix.startswith("v7") && getTriple().isOSBinFormatMachO());
  388. // FIXME: this is invalid for WindowsCE
  389. if (getTriple().isOSWindows())
  390. ThumbDefault = true;
  391. std::string ArchName;
  392. if (IsBigEndian)
  393. ArchName = "armeb";
  394. else
  395. ArchName = "arm";
  396. // Assembly files should start in ARM mode.
  397. if (InputType != types::TY_PP_Asm &&
  398. Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, ThumbDefault))
  399. {
  400. if (IsBigEndian)
  401. ArchName = "thumbeb";
  402. else
  403. ArchName = "thumb";
  404. }
  405. Triple.setArchName(ArchName + Suffix.str());
  406. return Triple.getTriple();
  407. }
  408. }
  409. }
  410. std::string ToolChain::ComputeEffectiveClangTriple(const ArgList &Args,
  411. types::ID InputType) const {
  412. return ComputeLLVMTriple(Args, InputType);
  413. }
  414. void ToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
  415. ArgStringList &CC1Args) const {
  416. // Each toolchain should provide the appropriate include flags.
  417. }
  418. void ToolChain::addClangTargetOptions(const ArgList &DriverArgs,
  419. ArgStringList &CC1Args) const {
  420. }
  421. void ToolChain::addClangWarningOptions(ArgStringList &CC1Args) const {}
  422. ToolChain::RuntimeLibType ToolChain::GetRuntimeLibType(
  423. const ArgList &Args) const
  424. {
  425. if (Arg *A = Args.getLastArg(options::OPT_rtlib_EQ)) {
  426. StringRef Value = A->getValue();
  427. if (Value == "compiler-rt")
  428. return ToolChain::RLT_CompilerRT;
  429. if (Value == "libgcc")
  430. return ToolChain::RLT_Libgcc;
  431. getDriver().Diag(diag::err_drv_invalid_rtlib_name)
  432. << A->getAsString(Args);
  433. }
  434. return GetDefaultRuntimeLibType();
  435. }
  436. ToolChain::CXXStdlibType ToolChain::GetCXXStdlibType(const ArgList &Args) const{
  437. if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) {
  438. StringRef Value = A->getValue();
  439. if (Value == "libc++")
  440. return ToolChain::CST_Libcxx;
  441. if (Value == "libstdc++")
  442. return ToolChain::CST_Libstdcxx;
  443. getDriver().Diag(diag::err_drv_invalid_stdlib_name)
  444. << A->getAsString(Args);
  445. }
  446. return ToolChain::CST_Libstdcxx;
  447. }
  448. /// \brief Utility function to add a system include directory to CC1 arguments.
  449. /*static*/ void ToolChain::addSystemInclude(const ArgList &DriverArgs,
  450. ArgStringList &CC1Args,
  451. const Twine &Path) {
  452. CC1Args.push_back("-internal-isystem");
  453. CC1Args.push_back(DriverArgs.MakeArgString(Path));
  454. }
  455. /// \brief Utility function to add a system include directory with extern "C"
  456. /// semantics to CC1 arguments.
  457. ///
  458. /// Note that this should be used rarely, and only for directories that
  459. /// historically and for legacy reasons are treated as having implicit extern
  460. /// "C" semantics. These semantics are *ignored* by and large today, but its
  461. /// important to preserve the preprocessor changes resulting from the
  462. /// classification.
  463. /*static*/ void ToolChain::addExternCSystemInclude(const ArgList &DriverArgs,
  464. ArgStringList &CC1Args,
  465. const Twine &Path) {
  466. CC1Args.push_back("-internal-externc-isystem");
  467. CC1Args.push_back(DriverArgs.MakeArgString(Path));
  468. }
  469. void ToolChain::addExternCSystemIncludeIfExists(const ArgList &DriverArgs,
  470. ArgStringList &CC1Args,
  471. const Twine &Path) {
  472. if (llvm::sys::fs::exists(Path))
  473. addExternCSystemInclude(DriverArgs, CC1Args, Path);
  474. }
  475. /// \brief Utility function to add a list of system include directories to CC1.
  476. /*static*/ void ToolChain::addSystemIncludes(const ArgList &DriverArgs,
  477. ArgStringList &CC1Args,
  478. ArrayRef<StringRef> Paths) {
  479. for (StringRef Path : Paths) {
  480. CC1Args.push_back("-internal-isystem");
  481. CC1Args.push_back(DriverArgs.MakeArgString(Path));
  482. }
  483. }
  484. void ToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
  485. ArgStringList &CC1Args) const {
  486. // Header search paths should be handled by each of the subclasses.
  487. // Historically, they have not been, and instead have been handled inside of
  488. // the CC1-layer frontend. As the logic is hoisted out, this generic function
  489. // will slowly stop being called.
  490. //
  491. // While it is being called, replicate a bit of a hack to propagate the
  492. // '-stdlib=' flag down to CC1 so that it can in turn customize the C++
  493. // header search paths with it. Once all systems are overriding this
  494. // function, the CC1 flag and this line can be removed.
  495. DriverArgs.AddAllArgs(CC1Args, options::OPT_stdlib_EQ);
  496. }
  497. void ToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
  498. ArgStringList &CmdArgs) const {
  499. CXXStdlibType Type = GetCXXStdlibType(Args);
  500. switch (Type) {
  501. case ToolChain::CST_Libcxx:
  502. CmdArgs.push_back("-lc++");
  503. break;
  504. case ToolChain::CST_Libstdcxx:
  505. CmdArgs.push_back("-lstdc++");
  506. break;
  507. }
  508. }
  509. void ToolChain::AddCCKextLibArgs(const ArgList &Args,
  510. ArgStringList &CmdArgs) const {
  511. CmdArgs.push_back("-lcc_kext");
  512. }
  513. bool ToolChain::AddFastMathRuntimeIfAvailable(const ArgList &Args,
  514. ArgStringList &CmdArgs) const {
  515. // Do not check for -fno-fast-math or -fno-unsafe-math when -Ofast passed
  516. // (to keep the linker options consistent with gcc and clang itself).
  517. if (!isOptimizationLevelFast(Args)) {
  518. // Check if -ffast-math or -funsafe-math.
  519. Arg *A =
  520. Args.getLastArg(options::OPT_ffast_math, options::OPT_fno_fast_math,
  521. options::OPT_funsafe_math_optimizations,
  522. options::OPT_fno_unsafe_math_optimizations);
  523. if (!A || A->getOption().getID() == options::OPT_fno_fast_math ||
  524. A->getOption().getID() == options::OPT_fno_unsafe_math_optimizations)
  525. return false;
  526. }
  527. // If crtfastmath.o exists add it to the arguments.
  528. std::string Path = GetFilePath("crtfastmath.o");
  529. if (Path == "crtfastmath.o") // Not found.
  530. return false;
  531. CmdArgs.push_back(Args.MakeArgString(Path));
  532. return true;
  533. }
  534. SanitizerMask ToolChain::getSupportedSanitizers() const {
  535. // Return sanitizers which don't require runtime support and are not
  536. // platform dependent.
  537. using namespace SanitizerKind;
  538. SanitizerMask Res = (Undefined & ~Vptr & ~Function) | (CFI & ~CFIICall) |
  539. CFICastStrict | UnsignedIntegerOverflow | LocalBounds;
  540. if (getTriple().getArch() == llvm::Triple::x86 ||
  541. getTriple().getArch() == llvm::Triple::x86_64)
  542. Res |= CFIICall;
  543. return Res;
  544. }