1 //===-- MSVC.cpp - MSVC ToolChain Implementations -------------------------===//
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
7 //===----------------------------------------------------------------------===//
10 #include "CommonArgs.h"
12 #include "clang/Basic/CharInfo.h"
13 #include "clang/Basic/Version.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"
33 #define WIN32_LEAN_AND_MEAN
42 // Don't support SetupApi on MinGW.
43 #define USE_MSVC_SETUP_API
45 // Make sure this comes before MSVCSetupApi.h
48 #include "MSVCSetupApi.h"
49 #include "llvm/Support/COM.h"
50 _COM_SMARTPTR_TYPEDEF(ISetupConfiguration, __uuidof(ISetupConfiguration));
51 _COM_SMARTPTR_TYPEDEF(ISetupConfiguration2, __uuidof(ISetupConfiguration2));
52 _COM_SMARTPTR_TYPEDEF(ISetupHelper, __uuidof(ISetupHelper));
53 _COM_SMARTPTR_TYPEDEF(IEnumSetupInstances, __uuidof(IEnumSetupInstances));
54 _COM_SMARTPTR_TYPEDEF(ISetupInstance, __uuidof(ISetupInstance));
55 _COM_SMARTPTR_TYPEDEF(ISetupInstance2, __uuidof(ISetupInstance2));
58 using namespace clang::driver;
59 using namespace clang::driver::toolchains;
60 using namespace clang::driver::tools;
61 using namespace clang;
62 using namespace llvm::opt;
65 // Forward declare this so there aren't too many things above the constructor.
66 static bool getSystemRegistryString(const char *keyPath, const char *valueName,
67 std::string &value, std::string *phValue);
69 // Check various environment variables to try and find a toolchain.
70 static bool findVCToolChainViaEnvironment(std::string &Path,
71 MSVCToolChain::ToolsetLayout &VSLayout) {
72 // These variables are typically set by vcvarsall.bat
73 // when launching a developer command prompt.
74 if (llvm::Optional<std::string> VCToolsInstallDir =
75 llvm::sys::Process::GetEnv("VCToolsInstallDir")) {
76 // This is only set by newer Visual Studios, and it leads straight to
77 // the toolchain directory.
78 Path = std::move(*VCToolsInstallDir);
79 VSLayout = MSVCToolChain::ToolsetLayout::VS2017OrNewer;
82 if (llvm::Optional<std::string> VCInstallDir =
83 llvm::sys::Process::GetEnv("VCINSTALLDIR")) {
84 // If the previous variable isn't set but this one is, then we've found
85 // an older Visual Studio. This variable is set by newer Visual Studios too,
86 // so this check has to appear second.
87 // In older Visual Studios, the VC directory is the toolchain.
88 Path = std::move(*VCInstallDir);
89 VSLayout = MSVCToolChain::ToolsetLayout::OlderVS;
93 // We couldn't find any VC environment variables. Let's walk through PATH and
94 // see if it leads us to a VC toolchain bin directory. If it does, pick the
95 // first one that we find.
96 if (llvm::Optional<std::string> PathEnv =
97 llvm::sys::Process::GetEnv("PATH")) {
98 llvm::SmallVector<llvm::StringRef, 8> PathEntries;
99 llvm::StringRef(*PathEnv).split(PathEntries, llvm::sys::EnvPathSeparator);
100 for (llvm::StringRef PathEntry : PathEntries) {
101 if (PathEntry.empty())
104 llvm::SmallString<256> ExeTestPath;
106 // If cl.exe doesn't exist, then this definitely isn't a VC toolchain.
107 ExeTestPath = PathEntry;
108 llvm::sys::path::append(ExeTestPath, "cl.exe");
109 if (!llvm::sys::fs::exists(ExeTestPath))
112 // cl.exe existing isn't a conclusive test for a VC toolchain; clang also
113 // has a cl.exe. So let's check for link.exe too.
114 ExeTestPath = PathEntry;
115 llvm::sys::path::append(ExeTestPath, "link.exe");
116 if (!llvm::sys::fs::exists(ExeTestPath))
119 // whatever/VC/bin --> old toolchain, VC dir is toolchain dir.
120 llvm::StringRef TestPath = PathEntry;
121 bool IsBin = llvm::sys::path::filename(TestPath).equals_lower("bin");
123 // Strip any architecture subdir like "amd64".
124 TestPath = llvm::sys::path::parent_path(TestPath);
125 IsBin = llvm::sys::path::filename(TestPath).equals_lower("bin");
128 llvm::StringRef ParentPath = llvm::sys::path::parent_path(TestPath);
129 llvm::StringRef ParentFilename = llvm::sys::path::filename(ParentPath);
130 if (ParentFilename == "VC") {
132 VSLayout = MSVCToolChain::ToolsetLayout::OlderVS;
135 if (ParentFilename == "x86ret" || ParentFilename == "x86chk"
136 || ParentFilename == "amd64ret" || ParentFilename == "amd64chk") {
138 VSLayout = MSVCToolChain::ToolsetLayout::DevDivInternal;
143 // This could be a new (>=VS2017) toolchain. If it is, we should find
144 // path components with these prefixes when walking backwards through
146 // Note: empty strings match anything.
147 llvm::StringRef ExpectedPrefixes[] = {"", "Host", "bin", "",
148 "MSVC", "Tools", "VC"};
150 auto It = llvm::sys::path::rbegin(PathEntry);
151 auto End = llvm::sys::path::rend(PathEntry);
152 for (llvm::StringRef Prefix : ExpectedPrefixes) {
155 if (!It->startswith(Prefix))
160 // We've found a new toolchain!
161 // Back up 3 times (/bin/Host/arch) to get the root path.
162 llvm::StringRef ToolChainPath(PathEntry);
163 for (int i = 0; i < 3; ++i)
164 ToolChainPath = llvm::sys::path::parent_path(ToolChainPath);
166 Path = ToolChainPath;
167 VSLayout = MSVCToolChain::ToolsetLayout::VS2017OrNewer;
178 // Query the Setup Config server for installs, then pick the newest version
179 // and find its default VC toolchain.
180 // This is the preferred way to discover new Visual Studios, as they're no
181 // longer listed in the registry.
182 static bool findVCToolChainViaSetupConfig(std::string &Path,
183 MSVCToolChain::ToolsetLayout &VSLayout) {
184 #if !defined(USE_MSVC_SETUP_API)
187 // FIXME: This really should be done once in the top-level program's main
188 // function, as it may have already been initialized with a different
189 // threading model otherwise.
190 llvm::sys::InitializeCOMRAII COM(llvm::sys::COMThreadingMode::SingleThreaded);
193 // _com_ptr_t will throw a _com_error if a COM calls fail.
194 // The LLVM coding standards forbid exception handling, so we'll have to
195 // stop them from being thrown in the first place.
196 // The destructor will put the regular error handler back when we leave
198 struct SuppressCOMErrorsRAII {
199 static void __stdcall handler(HRESULT hr, IErrorInfo *perrinfo) {}
201 SuppressCOMErrorsRAII() { _set_com_error_handler(handler); }
203 ~SuppressCOMErrorsRAII() { _set_com_error_handler(_com_raise_error); }
205 } COMErrorSuppressor;
207 ISetupConfigurationPtr Query;
208 HR = Query.CreateInstance(__uuidof(SetupConfiguration));
212 IEnumSetupInstancesPtr EnumInstances;
213 HR = ISetupConfiguration2Ptr(Query)->EnumAllInstances(&EnumInstances);
217 ISetupInstancePtr Instance;
218 HR = EnumInstances->Next(1, &Instance, nullptr);
222 ISetupInstancePtr NewestInstance;
223 Optional<uint64_t> NewestVersionNum;
225 bstr_t VersionString;
227 HR = Instance->GetInstallationVersion(VersionString.GetAddress());
230 HR = ISetupHelperPtr(Query)->ParseVersion(VersionString, &VersionNum);
233 if (!NewestVersionNum || (VersionNum > NewestVersionNum)) {
234 NewestInstance = Instance;
235 NewestVersionNum = VersionNum;
237 } while ((HR = EnumInstances->Next(1, &Instance, nullptr)) == S_OK);
243 HR = NewestInstance->ResolvePath(L"VC", VCPathWide.GetAddress());
247 std::string VCRootPath;
248 llvm::convertWideToUTF8(std::wstring(VCPathWide), VCRootPath);
250 llvm::SmallString<256> ToolsVersionFilePath(VCRootPath);
251 llvm::sys::path::append(ToolsVersionFilePath, "Auxiliary", "Build",
252 "Microsoft.VCToolsVersion.default.txt");
254 auto ToolsVersionFile = llvm::MemoryBuffer::getFile(ToolsVersionFilePath);
255 if (!ToolsVersionFile)
258 llvm::SmallString<256> ToolchainPath(VCRootPath);
259 llvm::sys::path::append(ToolchainPath, "Tools", "MSVC",
260 ToolsVersionFile->get()->getBuffer().rtrim());
261 if (!llvm::sys::fs::is_directory(ToolchainPath))
264 Path = ToolchainPath.str();
265 VSLayout = MSVCToolChain::ToolsetLayout::VS2017OrNewer;
270 // Look in the registry for Visual Studio installs, and use that to get
271 // a toolchain path. VS2017 and newer don't get added to the registry.
272 // So if we find something here, we know that it's an older version.
273 static bool findVCToolChainViaRegistry(std::string &Path,
274 MSVCToolChain::ToolsetLayout &VSLayout) {
275 std::string VSInstallPath;
276 if (getSystemRegistryString(R"(SOFTWARE\Microsoft\VisualStudio\$VERSION)",
277 "InstallDir", VSInstallPath, nullptr) ||
278 getSystemRegistryString(R"(SOFTWARE\Microsoft\VCExpress\$VERSION)",
279 "InstallDir", VSInstallPath, nullptr)) {
280 if (!VSInstallPath.empty()) {
281 llvm::SmallString<256> VCPath(llvm::StringRef(
282 VSInstallPath.c_str(), VSInstallPath.find(R"(\Common7\IDE)")));
283 llvm::sys::path::append(VCPath, "VC");
286 VSLayout = MSVCToolChain::ToolsetLayout::OlderVS;
293 // Try to find Exe from a Visual Studio distribution. This first tries to find
294 // an installed copy of Visual Studio and, failing that, looks in the PATH,
295 // making sure that whatever executable that's found is not a same-named exe
296 // from clang itself to prevent clang from falling back to itself.
297 static std::string FindVisualStudioExecutable(const ToolChain &TC,
299 const auto &MSVC = static_cast<const toolchains::MSVCToolChain &>(TC);
300 SmallString<128> FilePath(MSVC.getSubDirectoryPath(
301 toolchains::MSVCToolChain::SubDirectoryType::Bin));
302 llvm::sys::path::append(FilePath, Exe);
303 return llvm::sys::fs::can_execute(FilePath) ? FilePath.str() : Exe;
306 void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA,
307 const InputInfo &Output,
308 const InputInfoList &Inputs,
310 const char *LinkingOutput) const {
311 ArgStringList CmdArgs;
313 auto &TC = static_cast<const toolchains::MSVCToolChain &>(getToolChain());
315 assert((Output.isFilename() || Output.isNothing()) && "invalid output");
316 if (Output.isFilename())
318 Args.MakeArgString(std::string("-out:") + Output.getFilename()));
320 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles) &&
321 !C.getDriver().IsCLMode())
322 CmdArgs.push_back("-defaultlib:libcmt");
324 if (!llvm::sys::Process::GetEnv("LIB")) {
325 // If the VC environment hasn't been configured (perhaps because the user
326 // did not run vcvarsall), try to build a consistent link environment. If
327 // the environment variable is set however, assume the user knows what
329 CmdArgs.push_back(Args.MakeArgString(
331 TC.getSubDirectoryPath(
332 toolchains::MSVCToolChain::SubDirectoryType::Lib)));
334 CmdArgs.push_back(Args.MakeArgString(
336 TC.getSubDirectoryPath(toolchains::MSVCToolChain::SubDirectoryType::Lib,
339 if (TC.useUniversalCRT()) {
340 std::string UniversalCRTLibPath;
341 if (TC.getUniversalCRTLibraryPath(UniversalCRTLibPath))
343 Args.MakeArgString(Twine("-libpath:") + UniversalCRTLibPath));
346 std::string WindowsSdkLibPath;
347 if (TC.getWindowsSDKLibraryPath(WindowsSdkLibPath))
349 Args.MakeArgString(std::string("-libpath:") + WindowsSdkLibPath));
352 if (!C.getDriver().IsCLMode() && Args.hasArg(options::OPT_L))
353 for (const auto &LibPath : Args.getAllArgValues(options::OPT_L))
354 CmdArgs.push_back(Args.MakeArgString("-libpath:" + LibPath));
356 CmdArgs.push_back("-nologo");
358 if (Args.hasArg(options::OPT_g_Group, options::OPT__SLASH_Z7,
359 options::OPT__SLASH_Zd))
360 CmdArgs.push_back("-debug");
362 // Pass on /Brepro if it was passed to the compiler.
363 // Note that /Brepro maps to -mno-incremental-linker-compatible.
364 bool DefaultIncrementalLinkerCompatible =
365 C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment();
366 if (!Args.hasFlag(options::OPT_mincremental_linker_compatible,
367 options::OPT_mno_incremental_linker_compatible,
368 DefaultIncrementalLinkerCompatible))
369 CmdArgs.push_back("-Brepro");
371 bool DLL = Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd,
372 options::OPT_shared);
374 CmdArgs.push_back(Args.MakeArgString("-dll"));
376 SmallString<128> ImplibName(Output.getFilename());
377 llvm::sys::path::replace_extension(ImplibName, "lib");
378 CmdArgs.push_back(Args.MakeArgString(std::string("-implib:") + ImplibName));
381 if (TC.getSanitizerArgs().needsFuzzer()) {
382 if (!Args.hasArg(options::OPT_shared))
384 Args.MakeArgString(std::string("-wholearchive:") +
385 TC.getCompilerRTArgString(Args, "fuzzer")));
386 CmdArgs.push_back(Args.MakeArgString("-debug"));
387 // Prevent the linker from padding sections we use for instrumentation
389 CmdArgs.push_back(Args.MakeArgString("-incremental:no"));
392 if (TC.getSanitizerArgs().needsAsanRt()) {
393 CmdArgs.push_back(Args.MakeArgString("-debug"));
394 CmdArgs.push_back(Args.MakeArgString("-incremental:no"));
395 if (TC.getSanitizerArgs().needsSharedRt() ||
396 Args.hasArg(options::OPT__SLASH_MD, options::OPT__SLASH_MDd)) {
397 for (const auto &Lib : {"asan_dynamic", "asan_dynamic_runtime_thunk"})
398 CmdArgs.push_back(TC.getCompilerRTArgString(Args, Lib));
399 // Make sure the dynamic runtime thunk is not optimized out at link time
400 // to ensure proper SEH handling.
401 CmdArgs.push_back(Args.MakeArgString(
402 TC.getArch() == llvm::Triple::x86
403 ? "-include:___asan_seh_interceptor"
404 : "-include:__asan_seh_interceptor"));
405 // Make sure the linker consider all object files from the dynamic runtime
407 CmdArgs.push_back(Args.MakeArgString(std::string("-wholearchive:") +
408 TC.getCompilerRT(Args, "asan_dynamic_runtime_thunk")));
410 CmdArgs.push_back(TC.getCompilerRTArgString(Args, "asan_dll_thunk"));
412 for (const auto &Lib : {"asan", "asan_cxx"}) {
413 CmdArgs.push_back(TC.getCompilerRTArgString(Args, Lib));
414 // Make sure the linker consider all object files from the static lib.
415 // This is necessary because instrumented dlls need access to all the
416 // interface exported by the static lib in the main executable.
417 CmdArgs.push_back(Args.MakeArgString(std::string("-wholearchive:") +
418 TC.getCompilerRT(Args, Lib)));
423 Args.AddAllArgValues(CmdArgs, options::OPT__SLASH_link);
425 if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
426 options::OPT_fno_openmp, false)) {
427 CmdArgs.push_back("-nodefaultlib:vcomp.lib");
428 CmdArgs.push_back("-nodefaultlib:vcompd.lib");
429 CmdArgs.push_back(Args.MakeArgString(std::string("-libpath:") +
430 TC.getDriver().Dir + "/../lib"));
431 switch (TC.getDriver().getOpenMPRuntime(Args)) {
432 case Driver::OMPRT_OMP:
433 CmdArgs.push_back("-defaultlib:libomp.lib");
435 case Driver::OMPRT_IOMP5:
436 CmdArgs.push_back("-defaultlib:libiomp5md.lib");
438 case Driver::OMPRT_GOMP:
440 case Driver::OMPRT_Unknown:
441 // Already diagnosed.
446 // Add compiler-rt lib in case if it was explicitly
447 // specified as an argument for --rtlib option.
448 if (!Args.hasArg(options::OPT_nostdlib)) {
449 AddRunTimeLibs(TC, TC.getDriver(), CmdArgs, Args);
452 // Add filenames, libraries, and other linker inputs.
453 for (const auto &Input : Inputs) {
454 if (Input.isFilename()) {
455 CmdArgs.push_back(Input.getFilename());
459 const Arg &A = Input.getInputArg();
461 // Render -l options differently for the MSVC linker.
462 if (A.getOption().matches(options::OPT_l)) {
463 StringRef Lib = A.getValue();
464 const char *LinkLibArg;
465 if (Lib.endswith(".lib"))
466 LinkLibArg = Args.MakeArgString(Lib);
468 LinkLibArg = Args.MakeArgString(Lib + ".lib");
469 CmdArgs.push_back(LinkLibArg);
473 // Otherwise, this is some other kind of linker input option like -Wl, -z,
474 // or -L. Render it, even if MSVC doesn't understand it.
475 A.renderAsInput(Args, CmdArgs);
478 TC.addProfileRTLibs(Args, CmdArgs);
480 std::vector<const char *> Environment;
482 // We need to special case some linker paths. In the case of lld, we need to
483 // translate 'lld' into 'lld-link', and in the case of the regular msvc
484 // linker, we need to use a special search algorithm.
485 llvm::SmallString<128> linkPath;
486 StringRef Linker = Args.getLastArgValue(options::OPT_fuse_ld_EQ, "link");
487 if (Linker.equals_lower("lld"))
490 if (Linker.equals_lower("link")) {
491 // If we're using the MSVC linker, it's not sufficient to just use link
492 // from the program PATH, because other environments like GnuWin32 install
493 // their own link.exe which may come first.
494 linkPath = FindVisualStudioExecutable(TC, "link.exe");
496 if (!TC.FoundMSVCInstall() && !llvm::sys::fs::can_execute(linkPath)) {
497 llvm::SmallString<128> ClPath;
498 ClPath = TC.GetProgramPath("cl.exe");
499 if (llvm::sys::fs::can_execute(ClPath)) {
500 linkPath = llvm::sys::path::parent_path(ClPath);
501 llvm::sys::path::append(linkPath, "link.exe");
502 if (!llvm::sys::fs::can_execute(linkPath))
503 C.getDriver().Diag(clang::diag::warn_drv_msvc_not_found);
505 C.getDriver().Diag(clang::diag::warn_drv_msvc_not_found);
510 // When cross-compiling with VS2017 or newer, link.exe expects to have
511 // its containing bin directory at the top of PATH, followed by the
512 // native target bin directory.
513 // e.g. when compiling for x86 on an x64 host, PATH should start with:
514 // /bin/Hostx64/x86;/bin/Hostx64/x64
515 // This doesn't attempt to handle ToolsetLayout::DevDivInternal.
516 if (TC.getIsVS2017OrNewer() &&
517 llvm::Triple(llvm::sys::getProcessTriple()).getArch() != TC.getArch()) {
518 auto HostArch = llvm::Triple(llvm::sys::getProcessTriple()).getArch();
521 std::unique_ptr<wchar_t[], decltype(&FreeEnvironmentStringsW)>(
522 GetEnvironmentStringsW(), FreeEnvironmentStringsW);
524 goto SkipSettingEnvironment;
527 size_t EnvBlockLen = 0;
528 while (EnvBlockWide[EnvBlockLen] != L'\0') {
530 EnvBlockLen += std::wcslen(&EnvBlockWide[EnvBlockLen]) +
531 1 /*string null-terminator*/;
533 ++EnvBlockLen; // add the block null-terminator
535 std::string EnvBlock;
536 if (!llvm::convertUTF16ToUTF8String(
537 llvm::ArrayRef<char>(reinterpret_cast<char *>(EnvBlockWide.get()),
538 EnvBlockLen * sizeof(EnvBlockWide[0])),
540 goto SkipSettingEnvironment;
542 Environment.reserve(EnvCount);
544 // Now loop over each string in the block and copy them into the
545 // environment vector, adjusting the PATH variable as needed when we
547 for (const char *Cursor = EnvBlock.data(); *Cursor != '\0';) {
548 llvm::StringRef EnvVar(Cursor);
549 if (EnvVar.startswith_lower("path=")) {
550 using SubDirectoryType = toolchains::MSVCToolChain::SubDirectoryType;
551 constexpr size_t PrefixLen = 5; // strlen("path=")
552 Environment.push_back(Args.MakeArgString(
553 EnvVar.substr(0, PrefixLen) +
554 TC.getSubDirectoryPath(SubDirectoryType::Bin) +
555 llvm::Twine(llvm::sys::EnvPathSeparator) +
556 TC.getSubDirectoryPath(SubDirectoryType::Bin, "", HostArch) +
557 (EnvVar.size() > PrefixLen
558 ? llvm::Twine(llvm::sys::EnvPathSeparator) +
559 EnvVar.substr(PrefixLen)
562 Environment.push_back(Args.MakeArgString(EnvVar));
564 Cursor += EnvVar.size() + 1 /*null-terminator*/;
567 SkipSettingEnvironment:;
570 linkPath = TC.GetProgramPath(Linker.str().c_str());
573 auto LinkCmd = std::make_unique<Command>(
574 JA, *this, Args.MakeArgString(linkPath), CmdArgs, Inputs);
575 if (!Environment.empty())
576 LinkCmd->setEnvironment(Environment);
577 C.addCommand(std::move(LinkCmd));
580 void visualstudio::Compiler::ConstructJob(Compilation &C, const JobAction &JA,
581 const InputInfo &Output,
582 const InputInfoList &Inputs,
584 const char *LinkingOutput) const {
585 C.addCommand(GetCommand(C, JA, Output, Inputs, Args, LinkingOutput));
588 std::unique_ptr<Command> visualstudio::Compiler::GetCommand(
589 Compilation &C, const JobAction &JA, const InputInfo &Output,
590 const InputInfoList &Inputs, const ArgList &Args,
591 const char *LinkingOutput) const {
592 ArgStringList CmdArgs;
593 CmdArgs.push_back("/nologo");
594 CmdArgs.push_back("/c"); // Compile only.
595 CmdArgs.push_back("/W0"); // No warnings.
597 // The goal is to be able to invoke this tool correctly based on
598 // any flag accepted by clang-cl.
600 // These are spelled the same way in clang and cl.exe,.
601 Args.AddAllArgs(CmdArgs, {options::OPT_D, options::OPT_U, options::OPT_I});
603 // Optimization level.
604 if (Arg *A = Args.getLastArg(options::OPT_fbuiltin, options::OPT_fno_builtin))
605 CmdArgs.push_back(A->getOption().getID() == options::OPT_fbuiltin ? "/Oi"
607 if (Arg *A = Args.getLastArg(options::OPT_O, options::OPT_O0)) {
608 if (A->getOption().getID() == options::OPT_O0) {
609 CmdArgs.push_back("/Od");
611 CmdArgs.push_back("/Og");
613 StringRef OptLevel = A->getValue();
614 if (OptLevel == "s" || OptLevel == "z")
615 CmdArgs.push_back("/Os");
617 CmdArgs.push_back("/Ot");
619 CmdArgs.push_back("/Ob2");
622 if (Arg *A = Args.getLastArg(options::OPT_fomit_frame_pointer,
623 options::OPT_fno_omit_frame_pointer))
624 CmdArgs.push_back(A->getOption().getID() == options::OPT_fomit_frame_pointer
627 if (!Args.hasArg(options::OPT_fwritable_strings))
628 CmdArgs.push_back("/GF");
630 // Flags for which clang-cl has an alias.
631 // FIXME: How can we ensure this stays in sync with relevant clang-cl options?
633 if (Args.hasFlag(options::OPT__SLASH_GR_, options::OPT__SLASH_GR,
635 CmdArgs.push_back("/GR-");
637 if (Args.hasFlag(options::OPT__SLASH_GS_, options::OPT__SLASH_GS,
639 CmdArgs.push_back("/GS-");
641 if (Arg *A = Args.getLastArg(options::OPT_ffunction_sections,
642 options::OPT_fno_function_sections))
643 CmdArgs.push_back(A->getOption().getID() == options::OPT_ffunction_sections
646 if (Arg *A = Args.getLastArg(options::OPT_fdata_sections,
647 options::OPT_fno_data_sections))
649 A->getOption().getID() == options::OPT_fdata_sections ? "/Gw" : "/Gw-");
650 if (Args.hasArg(options::OPT_fsyntax_only))
651 CmdArgs.push_back("/Zs");
652 if (Args.hasArg(options::OPT_g_Flag, options::OPT_gline_tables_only,
653 options::OPT__SLASH_Z7))
654 CmdArgs.push_back("/Z7");
656 std::vector<std::string> Includes =
657 Args.getAllArgValues(options::OPT_include);
658 for (const auto &Include : Includes)
659 CmdArgs.push_back(Args.MakeArgString(std::string("/FI") + Include));
661 // Flags that can simply be passed through.
662 Args.AddAllArgs(CmdArgs, options::OPT__SLASH_LD);
663 Args.AddAllArgs(CmdArgs, options::OPT__SLASH_LDd);
664 Args.AddAllArgs(CmdArgs, options::OPT__SLASH_GX);
665 Args.AddAllArgs(CmdArgs, options::OPT__SLASH_GX_);
666 Args.AddAllArgs(CmdArgs, options::OPT__SLASH_EH);
667 Args.AddAllArgs(CmdArgs, options::OPT__SLASH_Zl);
669 // The order of these flags is relevant, so pick the last one.
670 if (Arg *A = Args.getLastArg(options::OPT__SLASH_MD, options::OPT__SLASH_MDd,
671 options::OPT__SLASH_MT, options::OPT__SLASH_MTd))
672 A->render(Args, CmdArgs);
674 // Use MSVC's default threadsafe statics behaviour unless there was a flag.
675 if (Arg *A = Args.getLastArg(options::OPT_fthreadsafe_statics,
676 options::OPT_fno_threadsafe_statics)) {
677 CmdArgs.push_back(A->getOption().getID() == options::OPT_fthreadsafe_statics
678 ? "/Zc:threadSafeInit"
679 : "/Zc:threadSafeInit-");
682 // Pass through all unknown arguments so that the fallback command can see
684 Args.AddAllArgs(CmdArgs, options::OPT_UNKNOWN);
687 assert(Inputs.size() == 1);
688 const InputInfo &II = Inputs[0];
689 assert(II.getType() == types::TY_C || II.getType() == types::TY_CXX);
690 CmdArgs.push_back(II.getType() == types::TY_C ? "/Tc" : "/Tp");
692 CmdArgs.push_back(II.getFilename());
694 II.getInputArg().renderAsInput(Args, CmdArgs);
697 assert(Output.getType() == types::TY_Object);
699 Args.MakeArgString(std::string("/Fo") + Output.getFilename());
700 CmdArgs.push_back(Fo);
702 std::string Exec = FindVisualStudioExecutable(getToolChain(), "cl.exe");
703 return std::make_unique<Command>(JA, *this, Args.MakeArgString(Exec),
707 MSVCToolChain::MSVCToolChain(const Driver &D, const llvm::Triple &Triple,
709 : ToolChain(D, Triple, Args), CudaInstallation(D, Triple, Args) {
710 getProgramPaths().push_back(getDriver().getInstalledDir());
711 if (getDriver().getInstalledDir() != getDriver().Dir)
712 getProgramPaths().push_back(getDriver().Dir);
714 // Check the environment first, since that's probably the user telling us
715 // what they want to use.
716 // Failing that, just try to find the newest Visual Studio version we can
717 // and use its default VC toolchain.
718 findVCToolChainViaEnvironment(VCToolChainPath, VSLayout) ||
719 findVCToolChainViaSetupConfig(VCToolChainPath, VSLayout) ||
720 findVCToolChainViaRegistry(VCToolChainPath, VSLayout);
723 Tool *MSVCToolChain::buildLinker() const {
724 return new tools::visualstudio::Linker(*this);
727 Tool *MSVCToolChain::buildAssembler() const {
728 if (getTriple().isOSBinFormatMachO())
729 return new tools::darwin::Assembler(*this);
730 getDriver().Diag(clang::diag::err_no_external_assembler);
734 bool MSVCToolChain::IsIntegratedAssemblerDefault() const {
738 bool MSVCToolChain::IsUnwindTablesDefault(const ArgList &Args) const {
739 // Don't emit unwind tables by default for MachO targets.
740 if (getTriple().isOSBinFormatMachO())
743 // All non-x86_32 Windows targets require unwind tables. However, LLVM
744 // doesn't know how to generate them for all targets, so only enable
745 // the ones that are actually implemented.
746 return getArch() == llvm::Triple::x86_64 ||
747 getArch() == llvm::Triple::aarch64;
750 bool MSVCToolChain::isPICDefault() const {
751 return getArch() == llvm::Triple::x86_64;
754 bool MSVCToolChain::isPIEDefault() const {
758 bool MSVCToolChain::isPICDefaultForced() const {
759 return getArch() == llvm::Triple::x86_64;
762 void MSVCToolChain::AddCudaIncludeArgs(const ArgList &DriverArgs,
763 ArgStringList &CC1Args) const {
764 CudaInstallation.AddCudaIncludeArgs(DriverArgs, CC1Args);
767 void MSVCToolChain::printVerboseInfo(raw_ostream &OS) const {
768 CudaInstallation.print(OS);
771 // Windows SDKs and VC Toolchains group their contents into subdirectories based
772 // on the target architecture. This function converts an llvm::Triple::ArchType
773 // to the corresponding subdirectory name.
774 static const char *llvmArchToWindowsSDKArch(llvm::Triple::ArchType Arch) {
775 using ArchType = llvm::Triple::ArchType;
779 case ArchType::x86_64:
783 case ArchType::aarch64:
790 // Similar to the above function, but for Visual Studios before VS2017.
791 static const char *llvmArchToLegacyVCArch(llvm::Triple::ArchType Arch) {
792 using ArchType = llvm::Triple::ArchType;
795 // x86 is default in legacy VC toolchains.
796 // e.g. x86 libs are directly in /lib as opposed to /lib/x86.
798 case ArchType::x86_64:
802 case ArchType::aarch64:
809 // Similar to the above function, but for DevDiv internal builds.
810 static const char *llvmArchToDevDivInternalArch(llvm::Triple::ArchType Arch) {
811 using ArchType = llvm::Triple::ArchType;
815 case ArchType::x86_64:
819 case ArchType::aarch64:
826 // Get the path to a specific subdirectory in the current toolchain for
827 // a given target architecture.
828 // VS2017 changed the VC toolchain layout, so this should be used instead
829 // of hardcoding paths.
831 MSVCToolChain::getSubDirectoryPath(SubDirectoryType Type,
832 llvm::StringRef SubdirParent,
833 llvm::Triple::ArchType TargetArch) const {
834 const char *SubdirName;
835 const char *IncludeName;
837 case ToolsetLayout::OlderVS:
838 SubdirName = llvmArchToLegacyVCArch(TargetArch);
839 IncludeName = "include";
841 case ToolsetLayout::VS2017OrNewer:
842 SubdirName = llvmArchToWindowsSDKArch(TargetArch);
843 IncludeName = "include";
845 case ToolsetLayout::DevDivInternal:
846 SubdirName = llvmArchToDevDivInternalArch(TargetArch);
851 llvm::SmallString<256> Path(VCToolChainPath);
852 if (!SubdirParent.empty())
853 llvm::sys::path::append(Path, SubdirParent);
856 case SubDirectoryType::Bin:
857 if (VSLayout == ToolsetLayout::VS2017OrNewer) {
858 const bool HostIsX64 =
859 llvm::Triple(llvm::sys::getProcessTriple()).isArch64Bit();
860 const char *const HostName = HostIsX64 ? "Hostx64" : "Hostx86";
861 llvm::sys::path::append(Path, "bin", HostName, SubdirName);
862 } else { // OlderVS or DevDivInternal
863 llvm::sys::path::append(Path, "bin", SubdirName);
866 case SubDirectoryType::Include:
867 llvm::sys::path::append(Path, IncludeName);
869 case SubDirectoryType::Lib:
870 llvm::sys::path::append(Path, "lib", SubdirName);
877 static bool readFullStringValue(HKEY hkey, const char *valueName,
878 std::string &value) {
879 std::wstring WideValueName;
880 if (!llvm::ConvertUTF8toWide(valueName, WideValueName))
886 // First just query for the required size.
887 result = RegQueryValueExW(hkey, WideValueName.c_str(), NULL, &type, NULL,
889 if (result != ERROR_SUCCESS || type != REG_SZ || !valueSize)
891 std::vector<BYTE> buffer(valueSize);
892 result = RegQueryValueExW(hkey, WideValueName.c_str(), NULL, NULL, &buffer[0],
894 if (result == ERROR_SUCCESS) {
895 std::wstring WideValue(reinterpret_cast<const wchar_t *>(buffer.data()),
896 valueSize / sizeof(wchar_t));
897 if (valueSize && WideValue.back() == L'\0') {
898 WideValue.pop_back();
900 // The destination buffer must be empty as an invariant of the conversion
901 // function; but this function is sometimes called in a loop that passes in
902 // the same buffer, however. Simply clear it out so we can overwrite it.
904 return llvm::convertWideToUTF8(WideValue, value);
910 /// Read registry string.
911 /// This also supports a means to look for high-versioned keys by use
912 /// of a $VERSION placeholder in the key path.
913 /// $VERSION in the key path is a placeholder for the version number,
914 /// causing the highest value path to be searched for and used.
915 /// I.e. "SOFTWARE\\Microsoft\\VisualStudio\\$VERSION".
916 /// There can be additional characters in the component. Only the numeric
917 /// characters are compared. This function only searches HKLM.
918 static bool getSystemRegistryString(const char *keyPath, const char *valueName,
919 std::string &value, std::string *phValue) {
923 HKEY hRootKey = HKEY_LOCAL_MACHINE;
926 bool returnValue = false;
928 const char *placeHolder = strstr(keyPath, "$VERSION");
929 std::string bestName;
930 // If we have a $VERSION placeholder, do the highest-version search.
932 const char *keyEnd = placeHolder - 1;
933 const char *nextKey = placeHolder;
934 // Find end of previous key.
935 while ((keyEnd > keyPath) && (*keyEnd != '\\'))
937 // Find end of key containing $VERSION.
938 while (*nextKey && (*nextKey != '\\'))
940 size_t partialKeyLength = keyEnd - keyPath;
941 char partialKey[256];
942 if (partialKeyLength >= sizeof(partialKey))
943 partialKeyLength = sizeof(partialKey) - 1;
944 strncpy(partialKey, keyPath, partialKeyLength);
945 partialKey[partialKeyLength] = '\0';
947 lResult = RegOpenKeyExA(hRootKey, partialKey, 0, KEY_READ | KEY_WOW64_32KEY,
949 if (lResult == ERROR_SUCCESS) {
951 double bestValue = 0.0;
952 DWORD index, size = sizeof(keyName) - 1;
953 for (index = 0; RegEnumKeyExA(hTopKey, index, keyName, &size, NULL, NULL,
954 NULL, NULL) == ERROR_SUCCESS;
956 const char *sp = keyName;
957 while (*sp && !isDigit(*sp))
961 const char *ep = sp + 1;
962 while (*ep && (isDigit(*ep) || (*ep == '.')))
965 strncpy(numBuf, sp, sizeof(numBuf) - 1);
966 numBuf[sizeof(numBuf) - 1] = '\0';
967 double dvalue = strtod(numBuf, NULL);
968 if (dvalue > bestValue) {
969 // Test that InstallDir is indeed there before keeping this index.
970 // Open the chosen key path remainder.
972 // Append rest of key.
973 bestName.append(nextKey);
974 lResult = RegOpenKeyExA(hTopKey, bestName.c_str(), 0,
975 KEY_READ | KEY_WOW64_32KEY, &hKey);
976 if (lResult == ERROR_SUCCESS) {
977 if (readFullStringValue(hKey, valueName, value)) {
986 size = sizeof(keyName) - 1;
988 RegCloseKey(hTopKey);
992 RegOpenKeyExA(hRootKey, keyPath, 0, KEY_READ | KEY_WOW64_32KEY, &hKey);
993 if (lResult == ERROR_SUCCESS) {
994 if (readFullStringValue(hKey, valueName, value))
1005 // Find the most recent version of Universal CRT or Windows 10 SDK.
1006 // vcvarsqueryregistry.bat from Visual Studio 2015 sorts entries in the include
1007 // directory by name and uses the last one of the list.
1008 // So we compare entry names lexicographically to find the greatest one.
1009 static bool getWindows10SDKVersionFromPath(const std::string &SDKPath,
1010 std::string &SDKVersion) {
1014 llvm::SmallString<128> IncludePath(SDKPath);
1015 llvm::sys::path::append(IncludePath, "Include");
1016 for (llvm::sys::fs::directory_iterator DirIt(IncludePath, EC), DirEnd;
1017 DirIt != DirEnd && !EC; DirIt.increment(EC)) {
1018 if (!llvm::sys::fs::is_directory(DirIt->path()))
1020 StringRef CandidateName = llvm::sys::path::filename(DirIt->path());
1021 // If WDK is installed, there could be subfolders like "wdf" in the
1022 // "Include" directory.
1023 // Allow only directories which names start with "10.".
1024 if (!CandidateName.startswith("10."))
1026 if (CandidateName > SDKVersion)
1027 SDKVersion = CandidateName;
1030 return !SDKVersion.empty();
1033 /// Get Windows SDK installation directory.
1034 static bool getWindowsSDKDir(std::string &Path, int &Major,
1035 std::string &WindowsSDKIncludeVersion,
1036 std::string &WindowsSDKLibVersion) {
1037 std::string RegistrySDKVersion;
1038 // Try the Windows registry.
1039 if (!getSystemRegistryString(
1040 "SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\$VERSION",
1041 "InstallationFolder", Path, &RegistrySDKVersion))
1043 if (Path.empty() || RegistrySDKVersion.empty())
1046 WindowsSDKIncludeVersion.clear();
1047 WindowsSDKLibVersion.clear();
1049 std::sscanf(RegistrySDKVersion.c_str(), "v%d.", &Major);
1053 // Windows SDK 8.x installs libraries in a folder whose names depend on the
1054 // version of the OS you're targeting. By default choose the newest, which
1055 // usually corresponds to the version of the OS you've installed the SDK on.
1056 const char *Tests[] = {"winv6.3", "win8", "win7"};
1057 for (const char *Test : Tests) {
1058 llvm::SmallString<128> TestPath(Path);
1059 llvm::sys::path::append(TestPath, "Lib", Test);
1060 if (llvm::sys::fs::exists(TestPath.c_str())) {
1061 WindowsSDKLibVersion = Test;
1065 return !WindowsSDKLibVersion.empty();
1068 if (!getWindows10SDKVersionFromPath(Path, WindowsSDKIncludeVersion))
1070 WindowsSDKLibVersion = WindowsSDKIncludeVersion;
1073 // Unsupported SDK version
1077 // Gets the library path required to link against the Windows SDK.
1078 bool MSVCToolChain::getWindowsSDKLibraryPath(std::string &path) const {
1079 std::string sdkPath;
1081 std::string windowsSDKIncludeVersion;
1082 std::string windowsSDKLibVersion;
1085 if (!getWindowsSDKDir(sdkPath, sdkMajor, windowsSDKIncludeVersion,
1086 windowsSDKLibVersion))
1089 llvm::SmallString<128> libPath(sdkPath);
1090 llvm::sys::path::append(libPath, "Lib");
1091 if (sdkMajor >= 8) {
1092 llvm::sys::path::append(libPath, windowsSDKLibVersion, "um",
1093 llvmArchToWindowsSDKArch(getArch()));
1095 switch (getArch()) {
1096 // In Windows SDK 7.x, x86 libraries are directly in the Lib folder.
1097 case llvm::Triple::x86:
1099 case llvm::Triple::x86_64:
1100 llvm::sys::path::append(libPath, "x64");
1102 case llvm::Triple::arm:
1103 // It is not necessary to link against Windows SDK 7.x when targeting ARM.
1110 path = libPath.str();
1114 // Check if the Include path of a specified version of Visual Studio contains
1115 // specific header files. If not, they are probably shipped with Universal CRT.
1116 bool MSVCToolChain::useUniversalCRT() const {
1117 llvm::SmallString<128> TestPath(
1118 getSubDirectoryPath(SubDirectoryType::Include));
1119 llvm::sys::path::append(TestPath, "stdlib.h");
1120 return !llvm::sys::fs::exists(TestPath);
1123 static bool getUniversalCRTSdkDir(std::string &Path, std::string &UCRTVersion) {
1124 // vcvarsqueryregistry.bat for Visual Studio 2015 queries the registry
1125 // for the specific key "KitsRoot10". So do we.
1126 if (!getSystemRegistryString(
1127 "SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots", "KitsRoot10",
1131 return getWindows10SDKVersionFromPath(Path, UCRTVersion);
1134 bool MSVCToolChain::getUniversalCRTLibraryPath(std::string &Path) const {
1135 std::string UniversalCRTSdkPath;
1136 std::string UCRTVersion;
1139 if (!getUniversalCRTSdkDir(UniversalCRTSdkPath, UCRTVersion))
1142 StringRef ArchName = llvmArchToWindowsSDKArch(getArch());
1143 if (ArchName.empty())
1146 llvm::SmallString<128> LibPath(UniversalCRTSdkPath);
1147 llvm::sys::path::append(LibPath, "Lib", UCRTVersion, "ucrt", ArchName);
1149 Path = LibPath.str();
1153 static VersionTuple getMSVCVersionFromTriple(const llvm::Triple &Triple) {
1154 unsigned Major, Minor, Micro;
1155 Triple.getEnvironmentVersion(Major, Minor, Micro);
1156 if (Major || Minor || Micro)
1157 return VersionTuple(Major, Minor, Micro);
1158 return VersionTuple();
1161 static VersionTuple getMSVCVersionFromExe(const std::string &BinDir) {
1162 VersionTuple Version;
1164 SmallString<128> ClExe(BinDir);
1165 llvm::sys::path::append(ClExe, "cl.exe");
1167 std::wstring ClExeWide;
1168 if (!llvm::ConvertUTF8toWide(ClExe.c_str(), ClExeWide))
1171 const DWORD VersionSize = ::GetFileVersionInfoSizeW(ClExeWide.c_str(),
1173 if (VersionSize == 0)
1176 SmallVector<uint8_t, 4 * 1024> VersionBlock(VersionSize);
1177 if (!::GetFileVersionInfoW(ClExeWide.c_str(), 0, VersionSize,
1178 VersionBlock.data()))
1181 VS_FIXEDFILEINFO *FileInfo = nullptr;
1182 UINT FileInfoSize = 0;
1183 if (!::VerQueryValueW(VersionBlock.data(), L"\\",
1184 reinterpret_cast<LPVOID *>(&FileInfo), &FileInfoSize) ||
1185 FileInfoSize < sizeof(*FileInfo))
1188 const unsigned Major = (FileInfo->dwFileVersionMS >> 16) & 0xFFFF;
1189 const unsigned Minor = (FileInfo->dwFileVersionMS ) & 0xFFFF;
1190 const unsigned Micro = (FileInfo->dwFileVersionLS >> 16) & 0xFFFF;
1192 Version = VersionTuple(Major, Minor, Micro);
1197 void MSVCToolChain::AddSystemIncludeWithSubfolder(
1198 const ArgList &DriverArgs, ArgStringList &CC1Args,
1199 const std::string &folder, const Twine &subfolder1, const Twine &subfolder2,
1200 const Twine &subfolder3) const {
1201 llvm::SmallString<128> path(folder);
1202 llvm::sys::path::append(path, subfolder1, subfolder2, subfolder3);
1203 addSystemInclude(DriverArgs, CC1Args, path);
1206 void MSVCToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
1207 ArgStringList &CC1Args) const {
1208 if (DriverArgs.hasArg(options::OPT_nostdinc))
1211 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
1212 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, getDriver().ResourceDir,
1216 // Add %INCLUDE%-like directories from the -imsvc flag.
1217 for (const auto &Path : DriverArgs.getAllArgValues(options::OPT__SLASH_imsvc))
1218 addSystemInclude(DriverArgs, CC1Args, Path);
1220 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
1223 // Honor %INCLUDE%. It should know essential search paths with vcvarsall.bat.
1224 if (llvm::Optional<std::string> cl_include_dir =
1225 llvm::sys::Process::GetEnv("INCLUDE")) {
1226 SmallVector<StringRef, 8> Dirs;
1227 StringRef(*cl_include_dir)
1228 .split(Dirs, ";", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
1229 for (StringRef Dir : Dirs)
1230 addSystemInclude(DriverArgs, CC1Args, Dir);
1235 // When built with access to the proper Windows APIs, try to actually find
1236 // the correct include paths first.
1237 if (!VCToolChainPath.empty()) {
1238 addSystemInclude(DriverArgs, CC1Args,
1239 getSubDirectoryPath(SubDirectoryType::Include));
1240 addSystemInclude(DriverArgs, CC1Args,
1241 getSubDirectoryPath(SubDirectoryType::Include, "atlmfc"));
1243 if (useUniversalCRT()) {
1244 std::string UniversalCRTSdkPath;
1245 std::string UCRTVersion;
1246 if (getUniversalCRTSdkDir(UniversalCRTSdkPath, UCRTVersion)) {
1247 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, UniversalCRTSdkPath,
1248 "Include", UCRTVersion, "ucrt");
1252 std::string WindowsSDKDir;
1254 std::string windowsSDKIncludeVersion;
1255 std::string windowsSDKLibVersion;
1256 if (getWindowsSDKDir(WindowsSDKDir, major, windowsSDKIncludeVersion,
1257 windowsSDKLibVersion)) {
1259 // Note: windowsSDKIncludeVersion is empty for SDKs prior to v10.
1260 // Anyway, llvm::sys::path::append is able to manage it.
1261 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
1262 "include", windowsSDKIncludeVersion,
1264 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
1265 "include", windowsSDKIncludeVersion,
1267 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
1268 "include", windowsSDKIncludeVersion,
1271 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
1280 // As a fallback, select default install paths.
1281 // FIXME: Don't guess drives and paths like this on Windows.
1282 const StringRef Paths[] = {
1283 "C:/Program Files/Microsoft Visual Studio 10.0/VC/include",
1284 "C:/Program Files/Microsoft Visual Studio 9.0/VC/include",
1285 "C:/Program Files/Microsoft Visual Studio 9.0/VC/PlatformSDK/Include",
1286 "C:/Program Files/Microsoft Visual Studio 8/VC/include",
1287 "C:/Program Files/Microsoft Visual Studio 8/VC/PlatformSDK/Include"
1289 addSystemIncludes(DriverArgs, CC1Args, Paths);
1293 void MSVCToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
1294 ArgStringList &CC1Args) const {
1295 // FIXME: There should probably be logic here to find libc++ on Windows.
1298 VersionTuple MSVCToolChain::computeMSVCVersion(const Driver *D,
1299 const ArgList &Args) const {
1300 bool IsWindowsMSVC = getTriple().isWindowsMSVCEnvironment();
1301 VersionTuple MSVT = ToolChain::computeMSVCVersion(D, Args);
1303 MSVT = getMSVCVersionFromTriple(getTriple());
1304 if (MSVT.empty() && IsWindowsMSVC)
1305 MSVT = getMSVCVersionFromExe(getSubDirectoryPath(SubDirectoryType::Bin));
1307 Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions,
1309 // -fms-compatibility-version=19.11 is default, aka 2017, 15.3
1310 MSVT = VersionTuple(19, 11);
1316 MSVCToolChain::ComputeEffectiveClangTriple(const ArgList &Args,
1317 types::ID InputType) const {
1318 // The MSVC version doesn't care about the architecture, even though it
1319 // may look at the triple internally.
1320 VersionTuple MSVT = computeMSVCVersion(/*D=*/nullptr, Args);
1321 MSVT = VersionTuple(MSVT.getMajor(), MSVT.getMinor().getValueOr(0),
1322 MSVT.getSubminor().getValueOr(0));
1324 // For the rest of the triple, however, a computed architecture name may
1326 llvm::Triple Triple(ToolChain::ComputeEffectiveClangTriple(Args, InputType));
1327 if (Triple.getEnvironment() == llvm::Triple::MSVC) {
1328 StringRef ObjFmt = Triple.getEnvironmentName().split('-').second;
1330 Triple.setEnvironmentName((Twine("msvc") + MSVT.getAsString()).str());
1332 Triple.setEnvironmentName(
1333 (Twine("msvc") + MSVT.getAsString() + Twine('-') + ObjFmt).str());
1335 return Triple.getTriple();
1338 SanitizerMask MSVCToolChain::getSupportedSanitizers() const {
1339 SanitizerMask Res = ToolChain::getSupportedSanitizers();
1340 Res |= SanitizerKind::Address;
1341 Res |= SanitizerKind::PointerCompare;
1342 Res |= SanitizerKind::PointerSubtract;
1343 Res |= SanitizerKind::Fuzzer;
1344 Res |= SanitizerKind::FuzzerNoLink;
1345 Res &= ~SanitizerKind::CFIMFCall;
1349 static void TranslateOptArg(Arg *A, llvm::opt::DerivedArgList &DAL,
1350 bool SupportsForcingFramePointer,
1351 const char *ExpandChar, const OptTable &Opts) {
1352 assert(A->getOption().matches(options::OPT__SLASH_O));
1354 StringRef OptStr = A->getValue();
1355 for (size_t I = 0, E = OptStr.size(); I != E; ++I) {
1356 const char &OptChar = *(OptStr.data() + I);
1364 // Ignore /O[12xd] flags that aren't the last one on the command line.
1365 // Only the last one gets expanded.
1366 if (&OptChar != ExpandChar) {
1370 if (OptChar == 'd') {
1371 DAL.AddFlagArg(A, Opts.getOption(options::OPT_O0));
1373 if (OptChar == '1') {
1374 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "s");
1375 } else if (OptChar == '2' || OptChar == 'x') {
1376 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
1377 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "2");
1379 if (SupportsForcingFramePointer &&
1380 !DAL.hasArgNoClaim(options::OPT_fno_omit_frame_pointer))
1381 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fomit_frame_pointer));
1382 if (OptChar == '1' || OptChar == '2')
1383 DAL.AddFlagArg(A, Opts.getOption(options::OPT_ffunction_sections));
1387 if (I + 1 != E && isdigit(OptStr[I + 1])) {
1388 switch (OptStr[I + 1]) {
1390 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_inline));
1393 DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_hint_functions));
1396 DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_functions));
1406 if (I + 1 != E && OptStr[I + 1] == '-') {
1408 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_builtin));
1410 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
1414 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "s");
1417 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "2");
1420 bool OmitFramePointer = true;
1421 if (I + 1 != E && OptStr[I + 1] == '-') {
1422 OmitFramePointer = false;
1425 if (SupportsForcingFramePointer) {
1426 if (OmitFramePointer)
1428 Opts.getOption(options::OPT_fomit_frame_pointer));
1431 A, Opts.getOption(options::OPT_fno_omit_frame_pointer));
1433 // Don't warn about /Oy- in x86-64 builds (where
1434 // SupportsForcingFramePointer is false). The flag having no effect
1435 // there is a compiler-internal optimization, and people shouldn't have
1436 // to special-case their build files for x86-64 clang-cl.
1445 static void TranslateDArg(Arg *A, llvm::opt::DerivedArgList &DAL,
1446 const OptTable &Opts) {
1447 assert(A->getOption().matches(options::OPT_D));
1449 StringRef Val = A->getValue();
1450 size_t Hash = Val.find('#');
1451 if (Hash == StringRef::npos || Hash > Val.find('=')) {
1456 std::string NewVal = Val;
1458 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_D), NewVal);
1461 llvm::opt::DerivedArgList *
1462 MSVCToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args,
1463 StringRef BoundArch, Action::OffloadKind) const {
1464 DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
1465 const OptTable &Opts = getDriver().getOpts();
1467 // /Oy and /Oy- don't have an effect on X86-64
1468 bool SupportsForcingFramePointer = getArch() != llvm::Triple::x86_64;
1470 // The -O[12xd] flag actually expands to several flags. We must desugar the
1471 // flags so that options embedded can be negated. For example, the '-O2' flag
1472 // enables '-Oy'. Expanding '-O2' into its constituent flags allows us to
1473 // correctly handle '-O2 -Oy-' where the trailing '-Oy-' disables a single
1476 // Note that this expansion logic only applies to the *last* of '[12xd]'.
1478 // First step is to search for the character we'd like to expand.
1479 const char *ExpandChar = nullptr;
1480 for (Arg *A : Args.filtered(options::OPT__SLASH_O)) {
1481 StringRef OptStr = A->getValue();
1482 for (size_t I = 0, E = OptStr.size(); I != E; ++I) {
1483 char OptChar = OptStr[I];
1484 char PrevChar = I > 0 ? OptStr[I - 1] : '0';
1485 if (PrevChar == 'b') {
1486 // OptChar does not expand; it's an argument to the previous char.
1489 if (OptChar == '1' || OptChar == '2' || OptChar == 'x' || OptChar == 'd')
1490 ExpandChar = OptStr.data() + I;
1494 for (Arg *A : Args) {
1495 if (A->getOption().matches(options::OPT__SLASH_O)) {
1496 // The -O flag actually takes an amalgam of other options. For example,
1497 // '/Ogyb2' is equivalent to '/Og' '/Oy' '/Ob2'.
1498 TranslateOptArg(A, *DAL, SupportsForcingFramePointer, ExpandChar, Opts);
1499 } else if (A->getOption().matches(options::OPT_D)) {
1500 // Translate -Dfoo#bar into -Dfoo=bar.
1501 TranslateDArg(A, *DAL, Opts);