MSVC.cpp 61 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625
  1. //===-- MSVC.cpp - MSVC ToolChain Implementations -------------------------===//
  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 "MSVC.h"
  9. #include "CommonArgs.h"
  10. #include "Darwin.h"
  11. #include "clang/Basic/CharInfo.h"
  12. #include "clang/Basic/Version.h"
  13. #include "clang/Config/config.h"
  14. #include "clang/Driver/Compilation.h"
  15. #include "clang/Driver/Driver.h"
  16. #include "clang/Driver/DriverDiagnostic.h"
  17. #include "clang/Driver/Options.h"
  18. #include "clang/Driver/SanitizerArgs.h"
  19. #include "llvm/ADT/StringExtras.h"
  20. #include "llvm/ADT/StringSwitch.h"
  21. #include "llvm/Option/Arg.h"
  22. #include "llvm/Option/ArgList.h"
  23. #include "llvm/Support/ConvertUTF.h"
  24. #include "llvm/Support/ErrorHandling.h"
  25. #include "llvm/Support/FileSystem.h"
  26. #include "llvm/Support/Host.h"
  27. #include "llvm/Support/MemoryBuffer.h"
  28. #include "llvm/Support/Path.h"
  29. #include "llvm/Support/Process.h"
  30. #include "llvm/Support/VirtualFileSystem.h"
  31. #include <cstdio>
  32. #ifdef _WIN32
  33. #define WIN32_LEAN_AND_MEAN
  34. #define NOGDI
  35. #ifndef NOMINMAX
  36. #define NOMINMAX
  37. #endif
  38. #include <windows.h>
  39. #endif
  40. #ifdef _MSC_VER
  41. // Don't support SetupApi on MinGW.
  42. #define USE_MSVC_SETUP_API
  43. // Make sure this comes before MSVCSetupApi.h
  44. #include <comdef.h>
  45. #ifdef __clang__
  46. #pragma clang diagnostic push
  47. #pragma clang diagnostic ignored "-Wnon-virtual-dtor"
  48. #endif
  49. #include "MSVCSetupApi.h"
  50. #ifdef __clang__
  51. #pragma clang diagnostic pop
  52. #endif
  53. #include "llvm/Support/COM.h"
  54. _COM_SMARTPTR_TYPEDEF(ISetupConfiguration, __uuidof(ISetupConfiguration));
  55. _COM_SMARTPTR_TYPEDEF(ISetupConfiguration2, __uuidof(ISetupConfiguration2));
  56. _COM_SMARTPTR_TYPEDEF(ISetupHelper, __uuidof(ISetupHelper));
  57. _COM_SMARTPTR_TYPEDEF(IEnumSetupInstances, __uuidof(IEnumSetupInstances));
  58. _COM_SMARTPTR_TYPEDEF(ISetupInstance, __uuidof(ISetupInstance));
  59. _COM_SMARTPTR_TYPEDEF(ISetupInstance2, __uuidof(ISetupInstance2));
  60. #endif
  61. using namespace clang::driver;
  62. using namespace clang::driver::toolchains;
  63. using namespace clang::driver::tools;
  64. using namespace clang;
  65. using namespace llvm::opt;
  66. // Windows SDKs and VC Toolchains group their contents into subdirectories based
  67. // on the target architecture. This function converts an llvm::Triple::ArchType
  68. // to the corresponding subdirectory name.
  69. static const char *llvmArchToWindowsSDKArch(llvm::Triple::ArchType Arch) {
  70. using ArchType = llvm::Triple::ArchType;
  71. switch (Arch) {
  72. case ArchType::x86:
  73. return "x86";
  74. case ArchType::x86_64:
  75. return "x64";
  76. case ArchType::arm:
  77. return "arm";
  78. case ArchType::aarch64:
  79. return "arm64";
  80. default:
  81. return "";
  82. }
  83. }
  84. // Similar to the above function, but for Visual Studios before VS2017.
  85. static const char *llvmArchToLegacyVCArch(llvm::Triple::ArchType Arch) {
  86. using ArchType = llvm::Triple::ArchType;
  87. switch (Arch) {
  88. case ArchType::x86:
  89. // x86 is default in legacy VC toolchains.
  90. // e.g. x86 libs are directly in /lib as opposed to /lib/x86.
  91. return "";
  92. case ArchType::x86_64:
  93. return "amd64";
  94. case ArchType::arm:
  95. return "arm";
  96. case ArchType::aarch64:
  97. return "arm64";
  98. default:
  99. return "";
  100. }
  101. }
  102. // Similar to the above function, but for DevDiv internal builds.
  103. static const char *llvmArchToDevDivInternalArch(llvm::Triple::ArchType Arch) {
  104. using ArchType = llvm::Triple::ArchType;
  105. switch (Arch) {
  106. case ArchType::x86:
  107. return "i386";
  108. case ArchType::x86_64:
  109. return "amd64";
  110. case ArchType::arm:
  111. return "arm";
  112. case ArchType::aarch64:
  113. return "arm64";
  114. default:
  115. return "";
  116. }
  117. }
  118. static bool canExecute(llvm::vfs::FileSystem &VFS, StringRef Path) {
  119. auto Status = VFS.status(Path);
  120. if (!Status)
  121. return false;
  122. return (Status->getPermissions() & llvm::sys::fs::perms::all_exe) != 0;
  123. }
  124. // Defined below.
  125. // Forward declare this so there aren't too many things above the constructor.
  126. static bool getSystemRegistryString(const char *keyPath, const char *valueName,
  127. std::string &value, std::string *phValue);
  128. static std::string getHighestNumericTupleInDirectory(llvm::vfs::FileSystem &VFS,
  129. StringRef Directory) {
  130. std::string Highest;
  131. llvm::VersionTuple HighestTuple;
  132. std::error_code EC;
  133. for (llvm::vfs::directory_iterator DirIt = VFS.dir_begin(Directory, EC),
  134. DirEnd;
  135. !EC && DirIt != DirEnd; DirIt.increment(EC)) {
  136. auto Status = VFS.status(DirIt->path());
  137. if (!Status || !Status->isDirectory())
  138. continue;
  139. StringRef CandidateName = llvm::sys::path::filename(DirIt->path());
  140. llvm::VersionTuple Tuple;
  141. if (Tuple.tryParse(CandidateName)) // tryParse() returns true on error.
  142. continue;
  143. if (Tuple > HighestTuple) {
  144. HighestTuple = Tuple;
  145. Highest = CandidateName.str();
  146. }
  147. }
  148. return Highest;
  149. }
  150. // Check command line arguments to try and find a toolchain.
  151. static bool
  152. findVCToolChainViaCommandLine(llvm::vfs::FileSystem &VFS, const ArgList &Args,
  153. std::string &Path,
  154. MSVCToolChain::ToolsetLayout &VSLayout) {
  155. // Don't validate the input; trust the value supplied by the user.
  156. // The primary motivation is to prevent unnecessary file and registry access.
  157. if (Arg *A = Args.getLastArg(options::OPT__SLASH_vctoolsdir,
  158. options::OPT__SLASH_winsysroot)) {
  159. if (A->getOption().getID() == options::OPT__SLASH_winsysroot) {
  160. llvm::SmallString<128> ToolsPath(A->getValue());
  161. llvm::sys::path::append(ToolsPath, "VC", "Tools", "MSVC");
  162. std::string VCToolsVersion;
  163. if (Arg *A = Args.getLastArg(options::OPT__SLASH_vctoolsversion))
  164. VCToolsVersion = A->getValue();
  165. else
  166. VCToolsVersion = getHighestNumericTupleInDirectory(VFS, ToolsPath);
  167. llvm::sys::path::append(ToolsPath, VCToolsVersion);
  168. Path = std::string(ToolsPath.str());
  169. } else {
  170. Path = A->getValue();
  171. }
  172. VSLayout = MSVCToolChain::ToolsetLayout::VS2017OrNewer;
  173. return true;
  174. }
  175. return false;
  176. }
  177. // Check various environment variables to try and find a toolchain.
  178. static bool
  179. findVCToolChainViaEnvironment(llvm::vfs::FileSystem &VFS, std::string &Path,
  180. MSVCToolChain::ToolsetLayout &VSLayout) {
  181. // These variables are typically set by vcvarsall.bat
  182. // when launching a developer command prompt.
  183. if (llvm::Optional<std::string> VCToolsInstallDir =
  184. llvm::sys::Process::GetEnv("VCToolsInstallDir")) {
  185. // This is only set by newer Visual Studios, and it leads straight to
  186. // the toolchain directory.
  187. Path = std::move(*VCToolsInstallDir);
  188. VSLayout = MSVCToolChain::ToolsetLayout::VS2017OrNewer;
  189. return true;
  190. }
  191. if (llvm::Optional<std::string> VCInstallDir =
  192. llvm::sys::Process::GetEnv("VCINSTALLDIR")) {
  193. // If the previous variable isn't set but this one is, then we've found
  194. // an older Visual Studio. This variable is set by newer Visual Studios too,
  195. // so this check has to appear second.
  196. // In older Visual Studios, the VC directory is the toolchain.
  197. Path = std::move(*VCInstallDir);
  198. VSLayout = MSVCToolChain::ToolsetLayout::OlderVS;
  199. return true;
  200. }
  201. // We couldn't find any VC environment variables. Let's walk through PATH and
  202. // see if it leads us to a VC toolchain bin directory. If it does, pick the
  203. // first one that we find.
  204. if (llvm::Optional<std::string> PathEnv =
  205. llvm::sys::Process::GetEnv("PATH")) {
  206. llvm::SmallVector<llvm::StringRef, 8> PathEntries;
  207. llvm::StringRef(*PathEnv).split(PathEntries, llvm::sys::EnvPathSeparator);
  208. for (llvm::StringRef PathEntry : PathEntries) {
  209. if (PathEntry.empty())
  210. continue;
  211. llvm::SmallString<256> ExeTestPath;
  212. // If cl.exe doesn't exist, then this definitely isn't a VC toolchain.
  213. ExeTestPath = PathEntry;
  214. llvm::sys::path::append(ExeTestPath, "cl.exe");
  215. if (!VFS.exists(ExeTestPath))
  216. continue;
  217. // cl.exe existing isn't a conclusive test for a VC toolchain; clang also
  218. // has a cl.exe. So let's check for link.exe too.
  219. ExeTestPath = PathEntry;
  220. llvm::sys::path::append(ExeTestPath, "link.exe");
  221. if (!VFS.exists(ExeTestPath))
  222. continue;
  223. // whatever/VC/bin --> old toolchain, VC dir is toolchain dir.
  224. llvm::StringRef TestPath = PathEntry;
  225. bool IsBin =
  226. llvm::sys::path::filename(TestPath).equals_insensitive("bin");
  227. if (!IsBin) {
  228. // Strip any architecture subdir like "amd64".
  229. TestPath = llvm::sys::path::parent_path(TestPath);
  230. IsBin = llvm::sys::path::filename(TestPath).equals_insensitive("bin");
  231. }
  232. if (IsBin) {
  233. llvm::StringRef ParentPath = llvm::sys::path::parent_path(TestPath);
  234. llvm::StringRef ParentFilename = llvm::sys::path::filename(ParentPath);
  235. if (ParentFilename.equals_insensitive("VC")) {
  236. Path = std::string(ParentPath);
  237. VSLayout = MSVCToolChain::ToolsetLayout::OlderVS;
  238. return true;
  239. }
  240. if (ParentFilename.equals_insensitive("x86ret") ||
  241. ParentFilename.equals_insensitive("x86chk") ||
  242. ParentFilename.equals_insensitive("amd64ret") ||
  243. ParentFilename.equals_insensitive("amd64chk")) {
  244. Path = std::string(ParentPath);
  245. VSLayout = MSVCToolChain::ToolsetLayout::DevDivInternal;
  246. return true;
  247. }
  248. } else {
  249. // This could be a new (>=VS2017) toolchain. If it is, we should find
  250. // path components with these prefixes when walking backwards through
  251. // the path.
  252. // Note: empty strings match anything.
  253. llvm::StringRef ExpectedPrefixes[] = {"", "Host", "bin", "",
  254. "MSVC", "Tools", "VC"};
  255. auto It = llvm::sys::path::rbegin(PathEntry);
  256. auto End = llvm::sys::path::rend(PathEntry);
  257. for (llvm::StringRef Prefix : ExpectedPrefixes) {
  258. if (It == End)
  259. goto NotAToolChain;
  260. if (!It->startswith_insensitive(Prefix))
  261. goto NotAToolChain;
  262. ++It;
  263. }
  264. // We've found a new toolchain!
  265. // Back up 3 times (/bin/Host/arch) to get the root path.
  266. llvm::StringRef ToolChainPath(PathEntry);
  267. for (int i = 0; i < 3; ++i)
  268. ToolChainPath = llvm::sys::path::parent_path(ToolChainPath);
  269. Path = std::string(ToolChainPath);
  270. VSLayout = MSVCToolChain::ToolsetLayout::VS2017OrNewer;
  271. return true;
  272. }
  273. NotAToolChain:
  274. continue;
  275. }
  276. }
  277. return false;
  278. }
  279. // Query the Setup Config server for installs, then pick the newest version
  280. // and find its default VC toolchain.
  281. // This is the preferred way to discover new Visual Studios, as they're no
  282. // longer listed in the registry.
  283. static bool
  284. findVCToolChainViaSetupConfig(llvm::vfs::FileSystem &VFS, std::string &Path,
  285. MSVCToolChain::ToolsetLayout &VSLayout) {
  286. #if !defined(USE_MSVC_SETUP_API)
  287. return false;
  288. #else
  289. // FIXME: This really should be done once in the top-level program's main
  290. // function, as it may have already been initialized with a different
  291. // threading model otherwise.
  292. llvm::sys::InitializeCOMRAII COM(llvm::sys::COMThreadingMode::SingleThreaded);
  293. HRESULT HR;
  294. // _com_ptr_t will throw a _com_error if a COM calls fail.
  295. // The LLVM coding standards forbid exception handling, so we'll have to
  296. // stop them from being thrown in the first place.
  297. // The destructor will put the regular error handler back when we leave
  298. // this scope.
  299. struct SuppressCOMErrorsRAII {
  300. static void __stdcall handler(HRESULT hr, IErrorInfo *perrinfo) {}
  301. SuppressCOMErrorsRAII() { _set_com_error_handler(handler); }
  302. ~SuppressCOMErrorsRAII() { _set_com_error_handler(_com_raise_error); }
  303. } COMErrorSuppressor;
  304. ISetupConfigurationPtr Query;
  305. HR = Query.CreateInstance(__uuidof(SetupConfiguration));
  306. if (FAILED(HR))
  307. return false;
  308. IEnumSetupInstancesPtr EnumInstances;
  309. HR = ISetupConfiguration2Ptr(Query)->EnumAllInstances(&EnumInstances);
  310. if (FAILED(HR))
  311. return false;
  312. ISetupInstancePtr Instance;
  313. HR = EnumInstances->Next(1, &Instance, nullptr);
  314. if (HR != S_OK)
  315. return false;
  316. ISetupInstancePtr NewestInstance;
  317. Optional<uint64_t> NewestVersionNum;
  318. do {
  319. bstr_t VersionString;
  320. uint64_t VersionNum;
  321. HR = Instance->GetInstallationVersion(VersionString.GetAddress());
  322. if (FAILED(HR))
  323. continue;
  324. HR = ISetupHelperPtr(Query)->ParseVersion(VersionString, &VersionNum);
  325. if (FAILED(HR))
  326. continue;
  327. if (!NewestVersionNum || (VersionNum > NewestVersionNum)) {
  328. NewestInstance = Instance;
  329. NewestVersionNum = VersionNum;
  330. }
  331. } while ((HR = EnumInstances->Next(1, &Instance, nullptr)) == S_OK);
  332. if (!NewestInstance)
  333. return false;
  334. bstr_t VCPathWide;
  335. HR = NewestInstance->ResolvePath(L"VC", VCPathWide.GetAddress());
  336. if (FAILED(HR))
  337. return false;
  338. std::string VCRootPath;
  339. llvm::convertWideToUTF8(std::wstring(VCPathWide), VCRootPath);
  340. llvm::SmallString<256> ToolsVersionFilePath(VCRootPath);
  341. llvm::sys::path::append(ToolsVersionFilePath, "Auxiliary", "Build",
  342. "Microsoft.VCToolsVersion.default.txt");
  343. auto ToolsVersionFile = llvm::MemoryBuffer::getFile(ToolsVersionFilePath);
  344. if (!ToolsVersionFile)
  345. return false;
  346. llvm::SmallString<256> ToolchainPath(VCRootPath);
  347. llvm::sys::path::append(ToolchainPath, "Tools", "MSVC",
  348. ToolsVersionFile->get()->getBuffer().rtrim());
  349. auto Status = VFS.status(ToolchainPath);
  350. if (!Status || !Status->isDirectory())
  351. return false;
  352. Path = std::string(ToolchainPath.str());
  353. VSLayout = MSVCToolChain::ToolsetLayout::VS2017OrNewer;
  354. return true;
  355. #endif
  356. }
  357. // Look in the registry for Visual Studio installs, and use that to get
  358. // a toolchain path. VS2017 and newer don't get added to the registry.
  359. // So if we find something here, we know that it's an older version.
  360. static bool findVCToolChainViaRegistry(std::string &Path,
  361. MSVCToolChain::ToolsetLayout &VSLayout) {
  362. std::string VSInstallPath;
  363. if (getSystemRegistryString(R"(SOFTWARE\Microsoft\VisualStudio\$VERSION)",
  364. "InstallDir", VSInstallPath, nullptr) ||
  365. getSystemRegistryString(R"(SOFTWARE\Microsoft\VCExpress\$VERSION)",
  366. "InstallDir", VSInstallPath, nullptr)) {
  367. if (!VSInstallPath.empty()) {
  368. llvm::SmallString<256> VCPath(llvm::StringRef(
  369. VSInstallPath.c_str(), VSInstallPath.find(R"(\Common7\IDE)")));
  370. llvm::sys::path::append(VCPath, "VC");
  371. Path = std::string(VCPath.str());
  372. VSLayout = MSVCToolChain::ToolsetLayout::OlderVS;
  373. return true;
  374. }
  375. }
  376. return false;
  377. }
  378. // Try to find Exe from a Visual Studio distribution. This first tries to find
  379. // an installed copy of Visual Studio and, failing that, looks in the PATH,
  380. // making sure that whatever executable that's found is not a same-named exe
  381. // from clang itself to prevent clang from falling back to itself.
  382. static std::string FindVisualStudioExecutable(const ToolChain &TC,
  383. const char *Exe) {
  384. const auto &MSVC = static_cast<const toolchains::MSVCToolChain &>(TC);
  385. SmallString<128> FilePath(MSVC.getSubDirectoryPath(
  386. toolchains::MSVCToolChain::SubDirectoryType::Bin));
  387. llvm::sys::path::append(FilePath, Exe);
  388. return std::string(canExecute(TC.getVFS(), FilePath) ? FilePath.str() : Exe);
  389. }
  390. void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA,
  391. const InputInfo &Output,
  392. const InputInfoList &Inputs,
  393. const ArgList &Args,
  394. const char *LinkingOutput) const {
  395. ArgStringList CmdArgs;
  396. auto &TC = static_cast<const toolchains::MSVCToolChain &>(getToolChain());
  397. assert((Output.isFilename() || Output.isNothing()) && "invalid output");
  398. if (Output.isFilename())
  399. CmdArgs.push_back(
  400. Args.MakeArgString(std::string("-out:") + Output.getFilename()));
  401. if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles) &&
  402. !C.getDriver().IsCLMode()) {
  403. CmdArgs.push_back("-defaultlib:libcmt");
  404. CmdArgs.push_back("-defaultlib:oldnames");
  405. }
  406. // If the VC environment hasn't been configured (perhaps because the user
  407. // did not run vcvarsall), try to build a consistent link environment. If
  408. // the environment variable is set however, assume the user knows what
  409. // they're doing. If the user passes /vctoolsdir or /winsdkdir, trust that
  410. // over env vars.
  411. if (const Arg *A = Args.getLastArg(options::OPT__SLASH_diasdkdir,
  412. options::OPT__SLASH_winsysroot)) {
  413. // cl.exe doesn't find the DIA SDK automatically, so this too requires
  414. // explicit flags and doesn't automatically look in "DIA SDK" relative
  415. // to the path we found for VCToolChainPath.
  416. llvm::SmallString<128> DIAPath(A->getValue());
  417. if (A->getOption().getID() == options::OPT__SLASH_winsysroot)
  418. llvm::sys::path::append(DIAPath, "DIA SDK");
  419. // The DIA SDK always uses the legacy vc arch, even in new MSVC versions.
  420. llvm::sys::path::append(DIAPath, "lib",
  421. llvmArchToLegacyVCArch(TC.getArch()));
  422. CmdArgs.push_back(Args.MakeArgString(Twine("-libpath:") + DIAPath));
  423. }
  424. if (!llvm::sys::Process::GetEnv("LIB") ||
  425. Args.getLastArg(options::OPT__SLASH_vctoolsdir,
  426. options::OPT__SLASH_winsysroot)) {
  427. CmdArgs.push_back(Args.MakeArgString(
  428. Twine("-libpath:") +
  429. TC.getSubDirectoryPath(
  430. toolchains::MSVCToolChain::SubDirectoryType::Lib)));
  431. CmdArgs.push_back(Args.MakeArgString(
  432. Twine("-libpath:") +
  433. TC.getSubDirectoryPath(toolchains::MSVCToolChain::SubDirectoryType::Lib,
  434. "atlmfc")));
  435. }
  436. if (!llvm::sys::Process::GetEnv("LIB") ||
  437. Args.getLastArg(options::OPT__SLASH_winsdkdir,
  438. options::OPT__SLASH_winsysroot)) {
  439. if (TC.useUniversalCRT()) {
  440. std::string UniversalCRTLibPath;
  441. if (TC.getUniversalCRTLibraryPath(Args, UniversalCRTLibPath))
  442. CmdArgs.push_back(
  443. Args.MakeArgString(Twine("-libpath:") + UniversalCRTLibPath));
  444. }
  445. std::string WindowsSdkLibPath;
  446. if (TC.getWindowsSDKLibraryPath(Args, WindowsSdkLibPath))
  447. CmdArgs.push_back(
  448. Args.MakeArgString(std::string("-libpath:") + WindowsSdkLibPath));
  449. }
  450. // Add the compiler-rt library directories to libpath if they exist to help
  451. // the linker find the various sanitizer, builtin, and profiling runtimes.
  452. for (const auto &LibPath : TC.getLibraryPaths()) {
  453. if (TC.getVFS().exists(LibPath))
  454. CmdArgs.push_back(Args.MakeArgString("-libpath:" + LibPath));
  455. }
  456. auto CRTPath = TC.getCompilerRTPath();
  457. if (TC.getVFS().exists(CRTPath))
  458. CmdArgs.push_back(Args.MakeArgString("-libpath:" + CRTPath));
  459. if (!C.getDriver().IsCLMode() && Args.hasArg(options::OPT_L))
  460. for (const auto &LibPath : Args.getAllArgValues(options::OPT_L))
  461. CmdArgs.push_back(Args.MakeArgString("-libpath:" + LibPath));
  462. CmdArgs.push_back("-nologo");
  463. if (Args.hasArg(options::OPT_g_Group, options::OPT__SLASH_Z7))
  464. CmdArgs.push_back("-debug");
  465. // If we specify /hotpatch, let the linker add padding in front of each
  466. // function, like MSVC does.
  467. if (Args.hasArg(options::OPT_fms_hotpatch, options::OPT__SLASH_hotpatch))
  468. CmdArgs.push_back("-functionpadmin");
  469. // Pass on /Brepro if it was passed to the compiler.
  470. // Note that /Brepro maps to -mno-incremental-linker-compatible.
  471. bool DefaultIncrementalLinkerCompatible =
  472. C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment();
  473. if (!Args.hasFlag(options::OPT_mincremental_linker_compatible,
  474. options::OPT_mno_incremental_linker_compatible,
  475. DefaultIncrementalLinkerCompatible))
  476. CmdArgs.push_back("-Brepro");
  477. bool DLL = Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd,
  478. options::OPT_shared);
  479. if (DLL) {
  480. CmdArgs.push_back(Args.MakeArgString("-dll"));
  481. SmallString<128> ImplibName(Output.getFilename());
  482. llvm::sys::path::replace_extension(ImplibName, "lib");
  483. CmdArgs.push_back(Args.MakeArgString(std::string("-implib:") + ImplibName));
  484. }
  485. if (TC.getSanitizerArgs(Args).needsFuzzer()) {
  486. if (!Args.hasArg(options::OPT_shared))
  487. CmdArgs.push_back(
  488. Args.MakeArgString(std::string("-wholearchive:") +
  489. TC.getCompilerRTArgString(Args, "fuzzer")));
  490. CmdArgs.push_back(Args.MakeArgString("-debug"));
  491. // Prevent the linker from padding sections we use for instrumentation
  492. // arrays.
  493. CmdArgs.push_back(Args.MakeArgString("-incremental:no"));
  494. }
  495. if (TC.getSanitizerArgs(Args).needsAsanRt()) {
  496. CmdArgs.push_back(Args.MakeArgString("-debug"));
  497. CmdArgs.push_back(Args.MakeArgString("-incremental:no"));
  498. if (TC.getSanitizerArgs(Args).needsSharedRt() ||
  499. Args.hasArg(options::OPT__SLASH_MD, options::OPT__SLASH_MDd)) {
  500. for (const auto &Lib : {"asan_dynamic", "asan_dynamic_runtime_thunk"})
  501. CmdArgs.push_back(TC.getCompilerRTArgString(Args, Lib));
  502. // Make sure the dynamic runtime thunk is not optimized out at link time
  503. // to ensure proper SEH handling.
  504. CmdArgs.push_back(Args.MakeArgString(
  505. TC.getArch() == llvm::Triple::x86
  506. ? "-include:___asan_seh_interceptor"
  507. : "-include:__asan_seh_interceptor"));
  508. // Make sure the linker consider all object files from the dynamic runtime
  509. // thunk.
  510. CmdArgs.push_back(Args.MakeArgString(std::string("-wholearchive:") +
  511. TC.getCompilerRT(Args, "asan_dynamic_runtime_thunk")));
  512. } else if (DLL) {
  513. CmdArgs.push_back(TC.getCompilerRTArgString(Args, "asan_dll_thunk"));
  514. } else {
  515. for (const auto &Lib : {"asan", "asan_cxx"}) {
  516. CmdArgs.push_back(TC.getCompilerRTArgString(Args, Lib));
  517. // Make sure the linker consider all object files from the static lib.
  518. // This is necessary because instrumented dlls need access to all the
  519. // interface exported by the static lib in the main executable.
  520. CmdArgs.push_back(Args.MakeArgString(std::string("-wholearchive:") +
  521. TC.getCompilerRT(Args, Lib)));
  522. }
  523. }
  524. }
  525. Args.AddAllArgValues(CmdArgs, options::OPT__SLASH_link);
  526. // Control Flow Guard checks
  527. if (Arg *A = Args.getLastArg(options::OPT__SLASH_guard)) {
  528. StringRef GuardArgs = A->getValue();
  529. if (GuardArgs.equals_insensitive("cf") ||
  530. GuardArgs.equals_insensitive("cf,nochecks")) {
  531. // MSVC doesn't yet support the "nochecks" modifier.
  532. CmdArgs.push_back("-guard:cf");
  533. } else if (GuardArgs.equals_insensitive("cf-")) {
  534. CmdArgs.push_back("-guard:cf-");
  535. } else if (GuardArgs.equals_insensitive("ehcont")) {
  536. CmdArgs.push_back("-guard:ehcont");
  537. } else if (GuardArgs.equals_insensitive("ehcont-")) {
  538. CmdArgs.push_back("-guard:ehcont-");
  539. }
  540. }
  541. if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
  542. options::OPT_fno_openmp, false)) {
  543. CmdArgs.push_back("-nodefaultlib:vcomp.lib");
  544. CmdArgs.push_back("-nodefaultlib:vcompd.lib");
  545. CmdArgs.push_back(Args.MakeArgString(std::string("-libpath:") +
  546. TC.getDriver().Dir + "/../lib"));
  547. switch (TC.getDriver().getOpenMPRuntime(Args)) {
  548. case Driver::OMPRT_OMP:
  549. CmdArgs.push_back("-defaultlib:libomp.lib");
  550. break;
  551. case Driver::OMPRT_IOMP5:
  552. CmdArgs.push_back("-defaultlib:libiomp5md.lib");
  553. break;
  554. case Driver::OMPRT_GOMP:
  555. break;
  556. case Driver::OMPRT_Unknown:
  557. // Already diagnosed.
  558. break;
  559. }
  560. }
  561. // Add compiler-rt lib in case if it was explicitly
  562. // specified as an argument for --rtlib option.
  563. if (!Args.hasArg(options::OPT_nostdlib)) {
  564. AddRunTimeLibs(TC, TC.getDriver(), CmdArgs, Args);
  565. }
  566. // Add filenames, libraries, and other linker inputs.
  567. for (const auto &Input : Inputs) {
  568. if (Input.isFilename()) {
  569. CmdArgs.push_back(Input.getFilename());
  570. continue;
  571. }
  572. const Arg &A = Input.getInputArg();
  573. // Render -l options differently for the MSVC linker.
  574. if (A.getOption().matches(options::OPT_l)) {
  575. StringRef Lib = A.getValue();
  576. const char *LinkLibArg;
  577. if (Lib.endswith(".lib"))
  578. LinkLibArg = Args.MakeArgString(Lib);
  579. else
  580. LinkLibArg = Args.MakeArgString(Lib + ".lib");
  581. CmdArgs.push_back(LinkLibArg);
  582. continue;
  583. }
  584. // Otherwise, this is some other kind of linker input option like -Wl, -z,
  585. // or -L. Render it, even if MSVC doesn't understand it.
  586. A.renderAsInput(Args, CmdArgs);
  587. }
  588. TC.addProfileRTLibs(Args, CmdArgs);
  589. std::vector<const char *> Environment;
  590. // We need to special case some linker paths. In the case of lld, we need to
  591. // translate 'lld' into 'lld-link', and in the case of the regular msvc
  592. // linker, we need to use a special search algorithm.
  593. llvm::SmallString<128> linkPath;
  594. StringRef Linker
  595. = Args.getLastArgValue(options::OPT_fuse_ld_EQ, CLANG_DEFAULT_LINKER);
  596. if (Linker.empty())
  597. Linker = "link";
  598. if (Linker.equals_insensitive("lld"))
  599. Linker = "lld-link";
  600. if (Linker.equals_insensitive("link")) {
  601. // If we're using the MSVC linker, it's not sufficient to just use link
  602. // from the program PATH, because other environments like GnuWin32 install
  603. // their own link.exe which may come first.
  604. linkPath = FindVisualStudioExecutable(TC, "link.exe");
  605. if (!TC.FoundMSVCInstall() && !canExecute(TC.getVFS(), linkPath)) {
  606. llvm::SmallString<128> ClPath;
  607. ClPath = TC.GetProgramPath("cl.exe");
  608. if (canExecute(TC.getVFS(), ClPath)) {
  609. linkPath = llvm::sys::path::parent_path(ClPath);
  610. llvm::sys::path::append(linkPath, "link.exe");
  611. if (!canExecute(TC.getVFS(), linkPath))
  612. C.getDriver().Diag(clang::diag::warn_drv_msvc_not_found);
  613. } else {
  614. C.getDriver().Diag(clang::diag::warn_drv_msvc_not_found);
  615. }
  616. }
  617. #ifdef _WIN32
  618. // When cross-compiling with VS2017 or newer, link.exe expects to have
  619. // its containing bin directory at the top of PATH, followed by the
  620. // native target bin directory.
  621. // e.g. when compiling for x86 on an x64 host, PATH should start with:
  622. // /bin/Hostx64/x86;/bin/Hostx64/x64
  623. // This doesn't attempt to handle ToolsetLayout::DevDivInternal.
  624. if (TC.getIsVS2017OrNewer() &&
  625. llvm::Triple(llvm::sys::getProcessTriple()).getArch() != TC.getArch()) {
  626. auto HostArch = llvm::Triple(llvm::sys::getProcessTriple()).getArch();
  627. auto EnvBlockWide =
  628. std::unique_ptr<wchar_t[], decltype(&FreeEnvironmentStringsW)>(
  629. GetEnvironmentStringsW(), FreeEnvironmentStringsW);
  630. if (!EnvBlockWide)
  631. goto SkipSettingEnvironment;
  632. size_t EnvCount = 0;
  633. size_t EnvBlockLen = 0;
  634. while (EnvBlockWide[EnvBlockLen] != L'\0') {
  635. ++EnvCount;
  636. EnvBlockLen += std::wcslen(&EnvBlockWide[EnvBlockLen]) +
  637. 1 /*string null-terminator*/;
  638. }
  639. ++EnvBlockLen; // add the block null-terminator
  640. std::string EnvBlock;
  641. if (!llvm::convertUTF16ToUTF8String(
  642. llvm::ArrayRef<char>(reinterpret_cast<char *>(EnvBlockWide.get()),
  643. EnvBlockLen * sizeof(EnvBlockWide[0])),
  644. EnvBlock))
  645. goto SkipSettingEnvironment;
  646. Environment.reserve(EnvCount);
  647. // Now loop over each string in the block and copy them into the
  648. // environment vector, adjusting the PATH variable as needed when we
  649. // find it.
  650. for (const char *Cursor = EnvBlock.data(); *Cursor != '\0';) {
  651. llvm::StringRef EnvVar(Cursor);
  652. if (EnvVar.startswith_insensitive("path=")) {
  653. using SubDirectoryType = toolchains::MSVCToolChain::SubDirectoryType;
  654. constexpr size_t PrefixLen = 5; // strlen("path=")
  655. Environment.push_back(Args.MakeArgString(
  656. EnvVar.substr(0, PrefixLen) +
  657. TC.getSubDirectoryPath(SubDirectoryType::Bin) +
  658. llvm::Twine(llvm::sys::EnvPathSeparator) +
  659. TC.getSubDirectoryPath(SubDirectoryType::Bin, "", HostArch) +
  660. (EnvVar.size() > PrefixLen
  661. ? llvm::Twine(llvm::sys::EnvPathSeparator) +
  662. EnvVar.substr(PrefixLen)
  663. : "")));
  664. } else {
  665. Environment.push_back(Args.MakeArgString(EnvVar));
  666. }
  667. Cursor += EnvVar.size() + 1 /*null-terminator*/;
  668. }
  669. }
  670. SkipSettingEnvironment:;
  671. #endif
  672. } else {
  673. linkPath = TC.GetProgramPath(Linker.str().c_str());
  674. }
  675. auto LinkCmd = std::make_unique<Command>(
  676. JA, *this, ResponseFileSupport::AtFileUTF16(),
  677. Args.MakeArgString(linkPath), CmdArgs, Inputs, Output);
  678. if (!Environment.empty())
  679. LinkCmd->setEnvironment(Environment);
  680. C.addCommand(std::move(LinkCmd));
  681. }
  682. MSVCToolChain::MSVCToolChain(const Driver &D, const llvm::Triple &Triple,
  683. const ArgList &Args)
  684. : ToolChain(D, Triple, Args), CudaInstallation(D, Triple, Args),
  685. RocmInstallation(D, Triple, Args) {
  686. getProgramPaths().push_back(getDriver().getInstalledDir());
  687. if (getDriver().getInstalledDir() != getDriver().Dir)
  688. getProgramPaths().push_back(getDriver().Dir);
  689. // Check the command line first, that's the user explicitly telling us what to
  690. // use. Check the environment next, in case we're being invoked from a VS
  691. // command prompt. Failing that, just try to find the newest Visual Studio
  692. // version we can and use its default VC toolchain.
  693. findVCToolChainViaCommandLine(getVFS(), Args, VCToolChainPath, VSLayout) ||
  694. findVCToolChainViaEnvironment(getVFS(), VCToolChainPath, VSLayout) ||
  695. findVCToolChainViaSetupConfig(getVFS(), VCToolChainPath, VSLayout) ||
  696. findVCToolChainViaRegistry(VCToolChainPath, VSLayout);
  697. }
  698. Tool *MSVCToolChain::buildLinker() const {
  699. return new tools::visualstudio::Linker(*this);
  700. }
  701. Tool *MSVCToolChain::buildAssembler() const {
  702. if (getTriple().isOSBinFormatMachO())
  703. return new tools::darwin::Assembler(*this);
  704. getDriver().Diag(clang::diag::err_no_external_assembler);
  705. return nullptr;
  706. }
  707. bool MSVCToolChain::IsIntegratedAssemblerDefault() const {
  708. return true;
  709. }
  710. bool MSVCToolChain::IsUnwindTablesDefault(const ArgList &Args) const {
  711. // Don't emit unwind tables by default for MachO targets.
  712. if (getTriple().isOSBinFormatMachO())
  713. return false;
  714. // All non-x86_32 Windows targets require unwind tables. However, LLVM
  715. // doesn't know how to generate them for all targets, so only enable
  716. // the ones that are actually implemented.
  717. return getArch() == llvm::Triple::x86_64 ||
  718. getArch() == llvm::Triple::aarch64;
  719. }
  720. bool MSVCToolChain::isPICDefault() const {
  721. return getArch() == llvm::Triple::x86_64 ||
  722. getArch() == llvm::Triple::aarch64;
  723. }
  724. bool MSVCToolChain::isPIEDefault(const llvm::opt::ArgList &Args) const {
  725. return false;
  726. }
  727. bool MSVCToolChain::isPICDefaultForced() const {
  728. return getArch() == llvm::Triple::x86_64 ||
  729. getArch() == llvm::Triple::aarch64;
  730. }
  731. void MSVCToolChain::AddCudaIncludeArgs(const ArgList &DriverArgs,
  732. ArgStringList &CC1Args) const {
  733. CudaInstallation.AddCudaIncludeArgs(DriverArgs, CC1Args);
  734. }
  735. void MSVCToolChain::AddHIPIncludeArgs(const ArgList &DriverArgs,
  736. ArgStringList &CC1Args) const {
  737. RocmInstallation.AddHIPIncludeArgs(DriverArgs, CC1Args);
  738. }
  739. void MSVCToolChain::printVerboseInfo(raw_ostream &OS) const {
  740. CudaInstallation.print(OS);
  741. RocmInstallation.print(OS);
  742. }
  743. // Get the path to a specific subdirectory in the current toolchain for
  744. // a given target architecture.
  745. // VS2017 changed the VC toolchain layout, so this should be used instead
  746. // of hardcoding paths.
  747. std::string
  748. MSVCToolChain::getSubDirectoryPath(SubDirectoryType Type,
  749. llvm::StringRef SubdirParent,
  750. llvm::Triple::ArchType TargetArch) const {
  751. const char *SubdirName;
  752. const char *IncludeName;
  753. switch (VSLayout) {
  754. case ToolsetLayout::OlderVS:
  755. SubdirName = llvmArchToLegacyVCArch(TargetArch);
  756. IncludeName = "include";
  757. break;
  758. case ToolsetLayout::VS2017OrNewer:
  759. SubdirName = llvmArchToWindowsSDKArch(TargetArch);
  760. IncludeName = "include";
  761. break;
  762. case ToolsetLayout::DevDivInternal:
  763. SubdirName = llvmArchToDevDivInternalArch(TargetArch);
  764. IncludeName = "inc";
  765. break;
  766. }
  767. llvm::SmallString<256> Path(VCToolChainPath);
  768. if (!SubdirParent.empty())
  769. llvm::sys::path::append(Path, SubdirParent);
  770. switch (Type) {
  771. case SubDirectoryType::Bin:
  772. if (VSLayout == ToolsetLayout::VS2017OrNewer) {
  773. const bool HostIsX64 =
  774. llvm::Triple(llvm::sys::getProcessTriple()).isArch64Bit();
  775. const char *const HostName = HostIsX64 ? "Hostx64" : "Hostx86";
  776. llvm::sys::path::append(Path, "bin", HostName, SubdirName);
  777. } else { // OlderVS or DevDivInternal
  778. llvm::sys::path::append(Path, "bin", SubdirName);
  779. }
  780. break;
  781. case SubDirectoryType::Include:
  782. llvm::sys::path::append(Path, IncludeName);
  783. break;
  784. case SubDirectoryType::Lib:
  785. llvm::sys::path::append(Path, "lib", SubdirName);
  786. break;
  787. }
  788. return std::string(Path.str());
  789. }
  790. #ifdef _WIN32
  791. static bool readFullStringValue(HKEY hkey, const char *valueName,
  792. std::string &value) {
  793. std::wstring WideValueName;
  794. if (!llvm::ConvertUTF8toWide(valueName, WideValueName))
  795. return false;
  796. DWORD result = 0;
  797. DWORD valueSize = 0;
  798. DWORD type = 0;
  799. // First just query for the required size.
  800. result = RegQueryValueExW(hkey, WideValueName.c_str(), NULL, &type, NULL,
  801. &valueSize);
  802. if (result != ERROR_SUCCESS || type != REG_SZ || !valueSize)
  803. return false;
  804. std::vector<BYTE> buffer(valueSize);
  805. result = RegQueryValueExW(hkey, WideValueName.c_str(), NULL, NULL, &buffer[0],
  806. &valueSize);
  807. if (result == ERROR_SUCCESS) {
  808. std::wstring WideValue(reinterpret_cast<const wchar_t *>(buffer.data()),
  809. valueSize / sizeof(wchar_t));
  810. if (valueSize && WideValue.back() == L'\0') {
  811. WideValue.pop_back();
  812. }
  813. // The destination buffer must be empty as an invariant of the conversion
  814. // function; but this function is sometimes called in a loop that passes in
  815. // the same buffer, however. Simply clear it out so we can overwrite it.
  816. value.clear();
  817. return llvm::convertWideToUTF8(WideValue, value);
  818. }
  819. return false;
  820. }
  821. #endif
  822. /// Read registry string.
  823. /// This also supports a means to look for high-versioned keys by use
  824. /// of a $VERSION placeholder in the key path.
  825. /// $VERSION in the key path is a placeholder for the version number,
  826. /// causing the highest value path to be searched for and used.
  827. /// I.e. "SOFTWARE\\Microsoft\\VisualStudio\\$VERSION".
  828. /// There can be additional characters in the component. Only the numeric
  829. /// characters are compared. This function only searches HKLM.
  830. static bool getSystemRegistryString(const char *keyPath, const char *valueName,
  831. std::string &value, std::string *phValue) {
  832. #ifndef _WIN32
  833. return false;
  834. #else
  835. HKEY hRootKey = HKEY_LOCAL_MACHINE;
  836. HKEY hKey = NULL;
  837. long lResult;
  838. bool returnValue = false;
  839. const char *placeHolder = strstr(keyPath, "$VERSION");
  840. std::string bestName;
  841. // If we have a $VERSION placeholder, do the highest-version search.
  842. if (placeHolder) {
  843. const char *keyEnd = placeHolder - 1;
  844. const char *nextKey = placeHolder;
  845. // Find end of previous key.
  846. while ((keyEnd > keyPath) && (*keyEnd != '\\'))
  847. keyEnd--;
  848. // Find end of key containing $VERSION.
  849. while (*nextKey && (*nextKey != '\\'))
  850. nextKey++;
  851. size_t partialKeyLength = keyEnd - keyPath;
  852. char partialKey[256];
  853. if (partialKeyLength >= sizeof(partialKey))
  854. partialKeyLength = sizeof(partialKey) - 1;
  855. strncpy(partialKey, keyPath, partialKeyLength);
  856. partialKey[partialKeyLength] = '\0';
  857. HKEY hTopKey = NULL;
  858. lResult = RegOpenKeyExA(hRootKey, partialKey, 0, KEY_READ | KEY_WOW64_32KEY,
  859. &hTopKey);
  860. if (lResult == ERROR_SUCCESS) {
  861. char keyName[256];
  862. double bestValue = 0.0;
  863. DWORD index, size = sizeof(keyName) - 1;
  864. for (index = 0; RegEnumKeyExA(hTopKey, index, keyName, &size, NULL, NULL,
  865. NULL, NULL) == ERROR_SUCCESS;
  866. index++) {
  867. const char *sp = keyName;
  868. while (*sp && !isDigit(*sp))
  869. sp++;
  870. if (!*sp)
  871. continue;
  872. const char *ep = sp + 1;
  873. while (*ep && (isDigit(*ep) || (*ep == '.')))
  874. ep++;
  875. char numBuf[32];
  876. strncpy(numBuf, sp, sizeof(numBuf) - 1);
  877. numBuf[sizeof(numBuf) - 1] = '\0';
  878. double dvalue = strtod(numBuf, NULL);
  879. if (dvalue > bestValue) {
  880. // Test that InstallDir is indeed there before keeping this index.
  881. // Open the chosen key path remainder.
  882. bestName = keyName;
  883. // Append rest of key.
  884. bestName.append(nextKey);
  885. lResult = RegOpenKeyExA(hTopKey, bestName.c_str(), 0,
  886. KEY_READ | KEY_WOW64_32KEY, &hKey);
  887. if (lResult == ERROR_SUCCESS) {
  888. if (readFullStringValue(hKey, valueName, value)) {
  889. bestValue = dvalue;
  890. if (phValue)
  891. *phValue = bestName;
  892. returnValue = true;
  893. }
  894. RegCloseKey(hKey);
  895. }
  896. }
  897. size = sizeof(keyName) - 1;
  898. }
  899. RegCloseKey(hTopKey);
  900. }
  901. } else {
  902. lResult =
  903. RegOpenKeyExA(hRootKey, keyPath, 0, KEY_READ | KEY_WOW64_32KEY, &hKey);
  904. if (lResult == ERROR_SUCCESS) {
  905. if (readFullStringValue(hKey, valueName, value))
  906. returnValue = true;
  907. if (phValue)
  908. phValue->clear();
  909. RegCloseKey(hKey);
  910. }
  911. }
  912. return returnValue;
  913. #endif // _WIN32
  914. }
  915. // Find the most recent version of Universal CRT or Windows 10 SDK.
  916. // vcvarsqueryregistry.bat from Visual Studio 2015 sorts entries in the include
  917. // directory by name and uses the last one of the list.
  918. // So we compare entry names lexicographically to find the greatest one.
  919. static bool getWindows10SDKVersionFromPath(llvm::vfs::FileSystem &VFS,
  920. const std::string &SDKPath,
  921. std::string &SDKVersion) {
  922. llvm::SmallString<128> IncludePath(SDKPath);
  923. llvm::sys::path::append(IncludePath, "Include");
  924. SDKVersion = getHighestNumericTupleInDirectory(VFS, IncludePath);
  925. return !SDKVersion.empty();
  926. }
  927. static bool getWindowsSDKDirViaCommandLine(llvm::vfs::FileSystem &VFS,
  928. const ArgList &Args,
  929. std::string &Path, int &Major,
  930. std::string &Version) {
  931. if (Arg *A = Args.getLastArg(options::OPT__SLASH_winsdkdir,
  932. options::OPT__SLASH_winsysroot)) {
  933. // Don't validate the input; trust the value supplied by the user.
  934. // The motivation is to prevent unnecessary file and registry access.
  935. llvm::VersionTuple SDKVersion;
  936. if (Arg *A = Args.getLastArg(options::OPT__SLASH_winsdkversion))
  937. SDKVersion.tryParse(A->getValue());
  938. if (A->getOption().getID() == options::OPT__SLASH_winsysroot) {
  939. llvm::SmallString<128> SDKPath(A->getValue());
  940. llvm::sys::path::append(SDKPath, "Windows Kits");
  941. if (!SDKVersion.empty())
  942. llvm::sys::path::append(SDKPath, Twine(SDKVersion.getMajor()));
  943. else
  944. llvm::sys::path::append(
  945. SDKPath, getHighestNumericTupleInDirectory(VFS, SDKPath));
  946. Path = std::string(SDKPath.str());
  947. } else {
  948. Path = A->getValue();
  949. }
  950. if (!SDKVersion.empty()) {
  951. Major = SDKVersion.getMajor();
  952. Version = SDKVersion.getAsString();
  953. } else if (getWindows10SDKVersionFromPath(VFS, Path, Version)) {
  954. Major = 10;
  955. }
  956. return true;
  957. }
  958. return false;
  959. }
  960. /// Get Windows SDK installation directory.
  961. static bool getWindowsSDKDir(llvm::vfs::FileSystem &VFS, const ArgList &Args,
  962. std::string &Path, int &Major,
  963. std::string &WindowsSDKIncludeVersion,
  964. std::string &WindowsSDKLibVersion) {
  965. // Trust /winsdkdir and /winsdkversion if present.
  966. if (getWindowsSDKDirViaCommandLine(VFS, Args, Path, Major,
  967. WindowsSDKIncludeVersion)) {
  968. WindowsSDKLibVersion = WindowsSDKIncludeVersion;
  969. return true;
  970. }
  971. // FIXME: Try env vars (%WindowsSdkDir%, %UCRTVersion%) before going to registry.
  972. // Try the Windows registry.
  973. std::string RegistrySDKVersion;
  974. if (!getSystemRegistryString(
  975. "SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\$VERSION",
  976. "InstallationFolder", Path, &RegistrySDKVersion))
  977. return false;
  978. if (Path.empty() || RegistrySDKVersion.empty())
  979. return false;
  980. WindowsSDKIncludeVersion.clear();
  981. WindowsSDKLibVersion.clear();
  982. Major = 0;
  983. std::sscanf(RegistrySDKVersion.c_str(), "v%d.", &Major);
  984. if (Major <= 7)
  985. return true;
  986. if (Major == 8) {
  987. // Windows SDK 8.x installs libraries in a folder whose names depend on the
  988. // version of the OS you're targeting. By default choose the newest, which
  989. // usually corresponds to the version of the OS you've installed the SDK on.
  990. const char *Tests[] = {"winv6.3", "win8", "win7"};
  991. for (const char *Test : Tests) {
  992. llvm::SmallString<128> TestPath(Path);
  993. llvm::sys::path::append(TestPath, "Lib", Test);
  994. if (VFS.exists(TestPath)) {
  995. WindowsSDKLibVersion = Test;
  996. break;
  997. }
  998. }
  999. return !WindowsSDKLibVersion.empty();
  1000. }
  1001. if (Major == 10) {
  1002. if (!getWindows10SDKVersionFromPath(VFS, Path, WindowsSDKIncludeVersion))
  1003. return false;
  1004. WindowsSDKLibVersion = WindowsSDKIncludeVersion;
  1005. return true;
  1006. }
  1007. // Unsupported SDK version
  1008. return false;
  1009. }
  1010. // Gets the library path required to link against the Windows SDK.
  1011. bool MSVCToolChain::getWindowsSDKLibraryPath(
  1012. const ArgList &Args, std::string &path) const {
  1013. std::string sdkPath;
  1014. int sdkMajor = 0;
  1015. std::string windowsSDKIncludeVersion;
  1016. std::string windowsSDKLibVersion;
  1017. path.clear();
  1018. if (!getWindowsSDKDir(getVFS(), Args, sdkPath, sdkMajor,
  1019. windowsSDKIncludeVersion, windowsSDKLibVersion))
  1020. return false;
  1021. llvm::SmallString<128> libPath(sdkPath);
  1022. llvm::sys::path::append(libPath, "Lib");
  1023. if (sdkMajor >= 8) {
  1024. llvm::sys::path::append(libPath, windowsSDKLibVersion, "um",
  1025. llvmArchToWindowsSDKArch(getArch()));
  1026. } else {
  1027. switch (getArch()) {
  1028. // In Windows SDK 7.x, x86 libraries are directly in the Lib folder.
  1029. case llvm::Triple::x86:
  1030. break;
  1031. case llvm::Triple::x86_64:
  1032. llvm::sys::path::append(libPath, "x64");
  1033. break;
  1034. case llvm::Triple::arm:
  1035. // It is not necessary to link against Windows SDK 7.x when targeting ARM.
  1036. return false;
  1037. default:
  1038. return false;
  1039. }
  1040. }
  1041. path = std::string(libPath.str());
  1042. return true;
  1043. }
  1044. // Check if the Include path of a specified version of Visual Studio contains
  1045. // specific header files. If not, they are probably shipped with Universal CRT.
  1046. bool MSVCToolChain::useUniversalCRT() const {
  1047. llvm::SmallString<128> TestPath(
  1048. getSubDirectoryPath(SubDirectoryType::Include));
  1049. llvm::sys::path::append(TestPath, "stdlib.h");
  1050. return !getVFS().exists(TestPath);
  1051. }
  1052. static bool getUniversalCRTSdkDir(llvm::vfs::FileSystem &VFS,
  1053. const ArgList &Args, std::string &Path,
  1054. std::string &UCRTVersion) {
  1055. // If /winsdkdir is passed, use it as location for the UCRT too.
  1056. // FIXME: Should there be a dedicated /ucrtdir to override /winsdkdir?
  1057. int Major;
  1058. if (getWindowsSDKDirViaCommandLine(VFS, Args, Path, Major, UCRTVersion))
  1059. return true;
  1060. // FIXME: Try env vars (%UniversalCRTSdkDir%, %UCRTVersion%) before going to
  1061. // registry.
  1062. // vcvarsqueryregistry.bat for Visual Studio 2015 queries the registry
  1063. // for the specific key "KitsRoot10". So do we.
  1064. if (!getSystemRegistryString(
  1065. "SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots", "KitsRoot10",
  1066. Path, nullptr))
  1067. return false;
  1068. return getWindows10SDKVersionFromPath(VFS, Path, UCRTVersion);
  1069. }
  1070. bool MSVCToolChain::getUniversalCRTLibraryPath(const ArgList &Args,
  1071. std::string &Path) const {
  1072. std::string UniversalCRTSdkPath;
  1073. std::string UCRTVersion;
  1074. Path.clear();
  1075. if (!getUniversalCRTSdkDir(getVFS(), Args, UniversalCRTSdkPath, UCRTVersion))
  1076. return false;
  1077. StringRef ArchName = llvmArchToWindowsSDKArch(getArch());
  1078. if (ArchName.empty())
  1079. return false;
  1080. llvm::SmallString<128> LibPath(UniversalCRTSdkPath);
  1081. llvm::sys::path::append(LibPath, "Lib", UCRTVersion, "ucrt", ArchName);
  1082. Path = std::string(LibPath.str());
  1083. return true;
  1084. }
  1085. static VersionTuple getMSVCVersionFromExe(const std::string &BinDir) {
  1086. VersionTuple Version;
  1087. #ifdef _WIN32
  1088. SmallString<128> ClExe(BinDir);
  1089. llvm::sys::path::append(ClExe, "cl.exe");
  1090. std::wstring ClExeWide;
  1091. if (!llvm::ConvertUTF8toWide(ClExe.c_str(), ClExeWide))
  1092. return Version;
  1093. const DWORD VersionSize = ::GetFileVersionInfoSizeW(ClExeWide.c_str(),
  1094. nullptr);
  1095. if (VersionSize == 0)
  1096. return Version;
  1097. SmallVector<uint8_t, 4 * 1024> VersionBlock(VersionSize);
  1098. if (!::GetFileVersionInfoW(ClExeWide.c_str(), 0, VersionSize,
  1099. VersionBlock.data()))
  1100. return Version;
  1101. VS_FIXEDFILEINFO *FileInfo = nullptr;
  1102. UINT FileInfoSize = 0;
  1103. if (!::VerQueryValueW(VersionBlock.data(), L"\\",
  1104. reinterpret_cast<LPVOID *>(&FileInfo), &FileInfoSize) ||
  1105. FileInfoSize < sizeof(*FileInfo))
  1106. return Version;
  1107. const unsigned Major = (FileInfo->dwFileVersionMS >> 16) & 0xFFFF;
  1108. const unsigned Minor = (FileInfo->dwFileVersionMS ) & 0xFFFF;
  1109. const unsigned Micro = (FileInfo->dwFileVersionLS >> 16) & 0xFFFF;
  1110. Version = VersionTuple(Major, Minor, Micro);
  1111. #endif
  1112. return Version;
  1113. }
  1114. void MSVCToolChain::AddSystemIncludeWithSubfolder(
  1115. const ArgList &DriverArgs, ArgStringList &CC1Args,
  1116. const std::string &folder, const Twine &subfolder1, const Twine &subfolder2,
  1117. const Twine &subfolder3) const {
  1118. llvm::SmallString<128> path(folder);
  1119. llvm::sys::path::append(path, subfolder1, subfolder2, subfolder3);
  1120. addSystemInclude(DriverArgs, CC1Args, path);
  1121. }
  1122. void MSVCToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
  1123. ArgStringList &CC1Args) const {
  1124. if (DriverArgs.hasArg(options::OPT_nostdinc))
  1125. return;
  1126. if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
  1127. AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, getDriver().ResourceDir,
  1128. "include");
  1129. }
  1130. // Add %INCLUDE%-like directories from the -imsvc flag.
  1131. for (const auto &Path : DriverArgs.getAllArgValues(options::OPT__SLASH_imsvc))
  1132. addSystemInclude(DriverArgs, CC1Args, Path);
  1133. auto AddSystemIncludesFromEnv = [&](StringRef Var) -> bool {
  1134. if (auto Val = llvm::sys::Process::GetEnv(Var)) {
  1135. SmallVector<StringRef, 8> Dirs;
  1136. StringRef(*Val).split(Dirs, ";", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
  1137. if (!Dirs.empty()) {
  1138. addSystemIncludes(DriverArgs, CC1Args, Dirs);
  1139. return true;
  1140. }
  1141. }
  1142. return false;
  1143. };
  1144. // Add %INCLUDE%-like dirs via /external:env: flags.
  1145. for (const auto &Var :
  1146. DriverArgs.getAllArgValues(options::OPT__SLASH_external_env)) {
  1147. AddSystemIncludesFromEnv(Var);
  1148. }
  1149. // Add DIA SDK include if requested.
  1150. if (const Arg *A = DriverArgs.getLastArg(options::OPT__SLASH_diasdkdir,
  1151. options::OPT__SLASH_winsysroot)) {
  1152. // cl.exe doesn't find the DIA SDK automatically, so this too requires
  1153. // explicit flags and doesn't automatically look in "DIA SDK" relative
  1154. // to the path we found for VCToolChainPath.
  1155. llvm::SmallString<128> DIASDKPath(A->getValue());
  1156. if (A->getOption().getID() == options::OPT__SLASH_winsysroot)
  1157. llvm::sys::path::append(DIASDKPath, "DIA SDK");
  1158. AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, std::string(DIASDKPath),
  1159. "include");
  1160. }
  1161. if (DriverArgs.hasArg(options::OPT_nostdlibinc))
  1162. return;
  1163. // Honor %INCLUDE% and %EXTERNAL_INCLUDE%. It should have essential search
  1164. // paths set by vcvarsall.bat. Skip if the user expressly set a vctoolsdir.
  1165. if (!DriverArgs.getLastArg(options::OPT__SLASH_vctoolsdir,
  1166. options::OPT__SLASH_winsysroot)) {
  1167. bool Found = AddSystemIncludesFromEnv("INCLUDE");
  1168. Found |= AddSystemIncludesFromEnv("EXTERNAL_INCLUDE");
  1169. if (Found)
  1170. return;
  1171. }
  1172. // When built with access to the proper Windows APIs, try to actually find
  1173. // the correct include paths first.
  1174. if (!VCToolChainPath.empty()) {
  1175. addSystemInclude(DriverArgs, CC1Args,
  1176. getSubDirectoryPath(SubDirectoryType::Include));
  1177. addSystemInclude(DriverArgs, CC1Args,
  1178. getSubDirectoryPath(SubDirectoryType::Include, "atlmfc"));
  1179. if (useUniversalCRT()) {
  1180. std::string UniversalCRTSdkPath;
  1181. std::string UCRTVersion;
  1182. if (getUniversalCRTSdkDir(getVFS(), DriverArgs, UniversalCRTSdkPath,
  1183. UCRTVersion)) {
  1184. AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, UniversalCRTSdkPath,
  1185. "Include", UCRTVersion, "ucrt");
  1186. }
  1187. }
  1188. std::string WindowsSDKDir;
  1189. int major = 0;
  1190. std::string windowsSDKIncludeVersion;
  1191. std::string windowsSDKLibVersion;
  1192. if (getWindowsSDKDir(getVFS(), DriverArgs, WindowsSDKDir, major,
  1193. windowsSDKIncludeVersion, windowsSDKLibVersion)) {
  1194. if (major >= 8) {
  1195. // Note: windowsSDKIncludeVersion is empty for SDKs prior to v10.
  1196. // Anyway, llvm::sys::path::append is able to manage it.
  1197. AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
  1198. "Include", windowsSDKIncludeVersion,
  1199. "shared");
  1200. AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
  1201. "Include", windowsSDKIncludeVersion,
  1202. "um");
  1203. AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
  1204. "Include", windowsSDKIncludeVersion,
  1205. "winrt");
  1206. if (major >= 10) {
  1207. llvm::VersionTuple Tuple;
  1208. if (!Tuple.tryParse(windowsSDKIncludeVersion) &&
  1209. Tuple.getSubminor().getValueOr(0) >= 17134) {
  1210. AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
  1211. "Include", windowsSDKIncludeVersion,
  1212. "cppwinrt");
  1213. }
  1214. }
  1215. } else {
  1216. AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
  1217. "Include");
  1218. }
  1219. }
  1220. return;
  1221. }
  1222. #if defined(_WIN32)
  1223. // As a fallback, select default install paths.
  1224. // FIXME: Don't guess drives and paths like this on Windows.
  1225. const StringRef Paths[] = {
  1226. "C:/Program Files/Microsoft Visual Studio 10.0/VC/include",
  1227. "C:/Program Files/Microsoft Visual Studio 9.0/VC/include",
  1228. "C:/Program Files/Microsoft Visual Studio 9.0/VC/PlatformSDK/Include",
  1229. "C:/Program Files/Microsoft Visual Studio 8/VC/include",
  1230. "C:/Program Files/Microsoft Visual Studio 8/VC/PlatformSDK/Include"
  1231. };
  1232. addSystemIncludes(DriverArgs, CC1Args, Paths);
  1233. #endif
  1234. }
  1235. void MSVCToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
  1236. ArgStringList &CC1Args) const {
  1237. // FIXME: There should probably be logic here to find libc++ on Windows.
  1238. }
  1239. VersionTuple MSVCToolChain::computeMSVCVersion(const Driver *D,
  1240. const ArgList &Args) const {
  1241. bool IsWindowsMSVC = getTriple().isWindowsMSVCEnvironment();
  1242. VersionTuple MSVT = ToolChain::computeMSVCVersion(D, Args);
  1243. if (MSVT.empty())
  1244. MSVT = getTriple().getEnvironmentVersion();
  1245. if (MSVT.empty() && IsWindowsMSVC)
  1246. MSVT = getMSVCVersionFromExe(getSubDirectoryPath(SubDirectoryType::Bin));
  1247. if (MSVT.empty() &&
  1248. Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions,
  1249. IsWindowsMSVC)) {
  1250. // -fms-compatibility-version=19.20 is default, aka 2019, 16.x
  1251. MSVT = VersionTuple(19, 20);
  1252. }
  1253. return MSVT;
  1254. }
  1255. std::string
  1256. MSVCToolChain::ComputeEffectiveClangTriple(const ArgList &Args,
  1257. types::ID InputType) const {
  1258. // The MSVC version doesn't care about the architecture, even though it
  1259. // may look at the triple internally.
  1260. VersionTuple MSVT = computeMSVCVersion(/*D=*/nullptr, Args);
  1261. MSVT = VersionTuple(MSVT.getMajor(), MSVT.getMinor().getValueOr(0),
  1262. MSVT.getSubminor().getValueOr(0));
  1263. // For the rest of the triple, however, a computed architecture name may
  1264. // be needed.
  1265. llvm::Triple Triple(ToolChain::ComputeEffectiveClangTriple(Args, InputType));
  1266. if (Triple.getEnvironment() == llvm::Triple::MSVC) {
  1267. StringRef ObjFmt = Triple.getEnvironmentName().split('-').second;
  1268. if (ObjFmt.empty())
  1269. Triple.setEnvironmentName((Twine("msvc") + MSVT.getAsString()).str());
  1270. else
  1271. Triple.setEnvironmentName(
  1272. (Twine("msvc") + MSVT.getAsString() + Twine('-') + ObjFmt).str());
  1273. }
  1274. return Triple.getTriple();
  1275. }
  1276. SanitizerMask MSVCToolChain::getSupportedSanitizers() const {
  1277. SanitizerMask Res = ToolChain::getSupportedSanitizers();
  1278. Res |= SanitizerKind::Address;
  1279. Res |= SanitizerKind::PointerCompare;
  1280. Res |= SanitizerKind::PointerSubtract;
  1281. Res |= SanitizerKind::Fuzzer;
  1282. Res |= SanitizerKind::FuzzerNoLink;
  1283. Res &= ~SanitizerKind::CFIMFCall;
  1284. return Res;
  1285. }
  1286. static void TranslateOptArg(Arg *A, llvm::opt::DerivedArgList &DAL,
  1287. bool SupportsForcingFramePointer,
  1288. const char *ExpandChar, const OptTable &Opts) {
  1289. assert(A->getOption().matches(options::OPT__SLASH_O));
  1290. StringRef OptStr = A->getValue();
  1291. for (size_t I = 0, E = OptStr.size(); I != E; ++I) {
  1292. const char &OptChar = *(OptStr.data() + I);
  1293. switch (OptChar) {
  1294. default:
  1295. break;
  1296. case '1':
  1297. case '2':
  1298. case 'x':
  1299. case 'd':
  1300. // Ignore /O[12xd] flags that aren't the last one on the command line.
  1301. // Only the last one gets expanded.
  1302. if (&OptChar != ExpandChar) {
  1303. A->claim();
  1304. break;
  1305. }
  1306. if (OptChar == 'd') {
  1307. DAL.AddFlagArg(A, Opts.getOption(options::OPT_O0));
  1308. } else {
  1309. if (OptChar == '1') {
  1310. DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "s");
  1311. } else if (OptChar == '2' || OptChar == 'x') {
  1312. DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
  1313. DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "2");
  1314. }
  1315. if (SupportsForcingFramePointer &&
  1316. !DAL.hasArgNoClaim(options::OPT_fno_omit_frame_pointer))
  1317. DAL.AddFlagArg(A, Opts.getOption(options::OPT_fomit_frame_pointer));
  1318. if (OptChar == '1' || OptChar == '2')
  1319. DAL.AddFlagArg(A, Opts.getOption(options::OPT_ffunction_sections));
  1320. }
  1321. break;
  1322. case 'b':
  1323. if (I + 1 != E && isdigit(OptStr[I + 1])) {
  1324. switch (OptStr[I + 1]) {
  1325. case '0':
  1326. DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_inline));
  1327. break;
  1328. case '1':
  1329. DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_hint_functions));
  1330. break;
  1331. case '2':
  1332. DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_functions));
  1333. break;
  1334. }
  1335. ++I;
  1336. }
  1337. break;
  1338. case 'g':
  1339. A->claim();
  1340. break;
  1341. case 'i':
  1342. if (I + 1 != E && OptStr[I + 1] == '-') {
  1343. ++I;
  1344. DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_builtin));
  1345. } else {
  1346. DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
  1347. }
  1348. break;
  1349. case 's':
  1350. DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "s");
  1351. break;
  1352. case 't':
  1353. DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "2");
  1354. break;
  1355. case 'y': {
  1356. bool OmitFramePointer = true;
  1357. if (I + 1 != E && OptStr[I + 1] == '-') {
  1358. OmitFramePointer = false;
  1359. ++I;
  1360. }
  1361. if (SupportsForcingFramePointer) {
  1362. if (OmitFramePointer)
  1363. DAL.AddFlagArg(A,
  1364. Opts.getOption(options::OPT_fomit_frame_pointer));
  1365. else
  1366. DAL.AddFlagArg(
  1367. A, Opts.getOption(options::OPT_fno_omit_frame_pointer));
  1368. } else {
  1369. // Don't warn about /Oy- in x86-64 builds (where
  1370. // SupportsForcingFramePointer is false). The flag having no effect
  1371. // there is a compiler-internal optimization, and people shouldn't have
  1372. // to special-case their build files for x86-64 clang-cl.
  1373. A->claim();
  1374. }
  1375. break;
  1376. }
  1377. }
  1378. }
  1379. }
  1380. static void TranslateDArg(Arg *A, llvm::opt::DerivedArgList &DAL,
  1381. const OptTable &Opts) {
  1382. assert(A->getOption().matches(options::OPT_D));
  1383. StringRef Val = A->getValue();
  1384. size_t Hash = Val.find('#');
  1385. if (Hash == StringRef::npos || Hash > Val.find('=')) {
  1386. DAL.append(A);
  1387. return;
  1388. }
  1389. std::string NewVal = std::string(Val);
  1390. NewVal[Hash] = '=';
  1391. DAL.AddJoinedArg(A, Opts.getOption(options::OPT_D), NewVal);
  1392. }
  1393. static void TranslatePermissive(Arg *A, llvm::opt::DerivedArgList &DAL,
  1394. const OptTable &Opts) {
  1395. DAL.AddFlagArg(A, Opts.getOption(options::OPT__SLASH_Zc_twoPhase_));
  1396. DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_operator_names));
  1397. }
  1398. static void TranslatePermissiveMinus(Arg *A, llvm::opt::DerivedArgList &DAL,
  1399. const OptTable &Opts) {
  1400. DAL.AddFlagArg(A, Opts.getOption(options::OPT__SLASH_Zc_twoPhase));
  1401. DAL.AddFlagArg(A, Opts.getOption(options::OPT_foperator_names));
  1402. }
  1403. llvm::opt::DerivedArgList *
  1404. MSVCToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args,
  1405. StringRef BoundArch,
  1406. Action::OffloadKind OFK) const {
  1407. DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
  1408. const OptTable &Opts = getDriver().getOpts();
  1409. // /Oy and /Oy- don't have an effect on X86-64
  1410. bool SupportsForcingFramePointer = getArch() != llvm::Triple::x86_64;
  1411. // The -O[12xd] flag actually expands to several flags. We must desugar the
  1412. // flags so that options embedded can be negated. For example, the '-O2' flag
  1413. // enables '-Oy'. Expanding '-O2' into its constituent flags allows us to
  1414. // correctly handle '-O2 -Oy-' where the trailing '-Oy-' disables a single
  1415. // aspect of '-O2'.
  1416. //
  1417. // Note that this expansion logic only applies to the *last* of '[12xd]'.
  1418. // First step is to search for the character we'd like to expand.
  1419. const char *ExpandChar = nullptr;
  1420. for (Arg *A : Args.filtered(options::OPT__SLASH_O)) {
  1421. StringRef OptStr = A->getValue();
  1422. for (size_t I = 0, E = OptStr.size(); I != E; ++I) {
  1423. char OptChar = OptStr[I];
  1424. char PrevChar = I > 0 ? OptStr[I - 1] : '0';
  1425. if (PrevChar == 'b') {
  1426. // OptChar does not expand; it's an argument to the previous char.
  1427. continue;
  1428. }
  1429. if (OptChar == '1' || OptChar == '2' || OptChar == 'x' || OptChar == 'd')
  1430. ExpandChar = OptStr.data() + I;
  1431. }
  1432. }
  1433. for (Arg *A : Args) {
  1434. if (A->getOption().matches(options::OPT__SLASH_O)) {
  1435. // The -O flag actually takes an amalgam of other options. For example,
  1436. // '/Ogyb2' is equivalent to '/Og' '/Oy' '/Ob2'.
  1437. TranslateOptArg(A, *DAL, SupportsForcingFramePointer, ExpandChar, Opts);
  1438. } else if (A->getOption().matches(options::OPT_D)) {
  1439. // Translate -Dfoo#bar into -Dfoo=bar.
  1440. TranslateDArg(A, *DAL, Opts);
  1441. } else if (A->getOption().matches(options::OPT__SLASH_permissive)) {
  1442. // Expand /permissive
  1443. TranslatePermissive(A, *DAL, Opts);
  1444. } else if (A->getOption().matches(options::OPT__SLASH_permissive_)) {
  1445. // Expand /permissive-
  1446. TranslatePermissiveMinus(A, *DAL, Opts);
  1447. } else if (OFK != Action::OFK_HIP) {
  1448. // HIP Toolchain translates input args by itself.
  1449. DAL->append(A);
  1450. }
  1451. }
  1452. return DAL;
  1453. }
  1454. void MSVCToolChain::addClangTargetOptions(
  1455. const ArgList &DriverArgs, ArgStringList &CC1Args,
  1456. Action::OffloadKind DeviceOffloadKind) const {
  1457. // MSVC STL kindly allows removing all usages of typeid by defining
  1458. // _HAS_STATIC_RTTI to 0. Do so, when compiling with -fno-rtti
  1459. if (DriverArgs.hasArg(options::OPT_fno_rtti, options::OPT_frtti,
  1460. /*Default=*/false))
  1461. CC1Args.push_back("-D_HAS_STATIC_RTTI=0");
  1462. }