1 //===--- ToolChains.cpp - ToolChain Implementations -----------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 #include "CommonArgs.h"
13 #include "clang/Basic/CharInfo.h"
14 #include "clang/Basic/Version.h"
15 #include "clang/Driver/Compilation.h"
16 #include "clang/Driver/Driver.h"
17 #include "clang/Driver/DriverDiagnostic.h"
18 #include "clang/Driver/Options.h"
19 #include "clang/Driver/SanitizerArgs.h"
20 #include "llvm/ADT/StringExtras.h"
21 #include "llvm/ADT/StringSwitch.h"
22 #include "llvm/Config/llvm-config.h"
23 #include "llvm/Option/Arg.h"
24 #include "llvm/Option/ArgList.h"
25 #include "llvm/Support/ConvertUTF.h"
26 #include "llvm/Support/ErrorHandling.h"
27 #include "llvm/Support/FileSystem.h"
28 #include "llvm/Support/Host.h"
29 #include "llvm/Support/MemoryBuffer.h"
30 #include "llvm/Support/Path.h"
31 #include "llvm/Support/Process.h"
34 // Include the necessary headers to interface with the Windows registry and
36 #if defined(LLVM_ON_WIN32)
41 #define WIN32_LEAN_AND_MEAN
50 // Don't support SetupApi on MinGW.
51 #define USE_MSVC_SETUP_API
53 // Make sure this comes before MSVCSetupApi.h
56 #include "MSVCSetupApi.h"
57 #include "llvm/Support/COM.h"
58 _COM_SMARTPTR_TYPEDEF(ISetupConfiguration, __uuidof(ISetupConfiguration));
59 _COM_SMARTPTR_TYPEDEF(ISetupConfiguration2, __uuidof(ISetupConfiguration2));
60 _COM_SMARTPTR_TYPEDEF(ISetupHelper, __uuidof(ISetupHelper));
61 _COM_SMARTPTR_TYPEDEF(IEnumSetupInstances, __uuidof(IEnumSetupInstances));
62 _COM_SMARTPTR_TYPEDEF(ISetupInstance, __uuidof(ISetupInstance));
63 _COM_SMARTPTR_TYPEDEF(ISetupInstance2, __uuidof(ISetupInstance2));
66 using namespace clang::driver;
67 using namespace clang::driver::toolchains;
68 using namespace clang::driver::tools;
69 using namespace clang;
70 using namespace llvm::opt;
73 // Forward declare this so there aren't too many things above the constructor.
74 static bool getSystemRegistryString(const char *keyPath, const char *valueName,
75 std::string &value, std::string *phValue);
77 // Check various environment variables to try and find a toolchain.
78 static bool findVCToolChainViaEnvironment(std::string &Path,
79 bool &IsVS2017OrNewer) {
80 // These variables are typically set by vcvarsall.bat
81 // when launching a developer command prompt.
82 if (llvm::Optional<std::string> VCToolsInstallDir =
83 llvm::sys::Process::GetEnv("VCToolsInstallDir")) {
84 // This is only set by newer Visual Studios, and it leads straight to
85 // the toolchain directory.
86 Path = std::move(*VCToolsInstallDir);
87 IsVS2017OrNewer = true;
90 if (llvm::Optional<std::string> VCInstallDir =
91 llvm::sys::Process::GetEnv("VCINSTALLDIR")) {
92 // If the previous variable isn't set but this one is, then we've found
93 // an older Visual Studio. This variable is set by newer Visual Studios too,
94 // so this check has to appear second.
95 // In older Visual Studios, the VC directory is the toolchain.
96 Path = std::move(*VCInstallDir);
97 IsVS2017OrNewer = false;
101 // We couldn't find any VC environment variables. Let's walk through PATH and
102 // see if it leads us to a VC toolchain bin directory. If it does, pick the
103 // first one that we find.
104 if (llvm::Optional<std::string> PathEnv =
105 llvm::sys::Process::GetEnv("PATH")) {
106 llvm::SmallVector<llvm::StringRef, 8> PathEntries;
107 llvm::StringRef(*PathEnv).split(PathEntries, llvm::sys::EnvPathSeparator);
108 for (llvm::StringRef PathEntry : PathEntries) {
109 if (PathEntry.empty())
112 llvm::SmallString<256> ExeTestPath;
114 // If cl.exe doesn't exist, then this definitely isn't a VC toolchain.
115 ExeTestPath = PathEntry;
116 llvm::sys::path::append(ExeTestPath, "cl.exe");
117 if (!llvm::sys::fs::exists(ExeTestPath))
120 // cl.exe existing isn't a conclusive test for a VC toolchain; clang also
121 // has a cl.exe. So let's check for link.exe too.
122 ExeTestPath = PathEntry;
123 llvm::sys::path::append(ExeTestPath, "link.exe");
124 if (!llvm::sys::fs::exists(ExeTestPath))
127 // whatever/VC/bin --> old toolchain, VC dir is toolchain dir.
128 llvm::StringRef TestPath = PathEntry;
129 bool IsBin = llvm::sys::path::filename(TestPath).equals_lower("bin");
131 // Strip any architecture subdir like "amd64".
132 TestPath = llvm::sys::path::parent_path(TestPath);
133 IsBin = llvm::sys::path::filename(TestPath).equals_lower("bin");
136 llvm::StringRef ParentPath = llvm::sys::path::parent_path(TestPath);
137 if (llvm::sys::path::filename(ParentPath) == "VC") {
139 IsVS2017OrNewer = false;
144 // This could be a new (>=VS2017) toolchain. If it is, we should find
145 // path components with these prefixes when walking backwards through
147 // Note: empty strings match anything.
148 llvm::StringRef ExpectedPrefixes[] = {"", "Host", "bin", "",
149 "MSVC", "Tools", "VC"};
151 auto It = llvm::sys::path::rbegin(PathEntry);
152 auto End = llvm::sys::path::rend(PathEntry);
153 for (llvm::StringRef Prefix : ExpectedPrefixes) {
156 if (!It->startswith(Prefix))
161 // We've found a new toolchain!
162 // Back up 3 times (/bin/Host/arch) to get the root path.
163 llvm::StringRef ToolChainPath(PathEntry);
164 for (int i = 0; i < 3; ++i)
165 ToolChainPath = llvm::sys::path::parent_path(ToolChainPath);
167 Path = ToolChainPath;
168 IsVS2017OrNewer = true;
179 // Query the Setup Config server for installs, then pick the newest version
180 // and find its default VC toolchain.
181 // This is the preferred way to discover new Visual Studios, as they're no
182 // longer listed in the registry.
183 static bool findVCToolChainViaSetupConfig(std::string &Path,
184 bool &IsVS2017OrNewer) {
185 #if !defined(USE_MSVC_SETUP_API)
188 // FIXME: This really should be done once in the top-level program's main
189 // function, as it may have already been initialized with a different
190 // threading model otherwise.
191 llvm::sys::InitializeCOMRAII COM(llvm::sys::COMThreadingMode::SingleThreaded);
194 // _com_ptr_t will throw a _com_error if a COM calls fail.
195 // The LLVM coding standards forbid exception handling, so we'll have to
196 // stop them from being thrown in the first place.
197 // The destructor will put the regular error handler back when we leave
199 struct SuppressCOMErrorsRAII {
200 static void __stdcall handler(HRESULT hr, IErrorInfo *perrinfo) {}
202 SuppressCOMErrorsRAII() { _set_com_error_handler(handler); }
204 ~SuppressCOMErrorsRAII() { _set_com_error_handler(_com_raise_error); }
206 } COMErrorSuppressor;
208 ISetupConfigurationPtr Query;
209 HR = Query.CreateInstance(__uuidof(SetupConfiguration));
213 IEnumSetupInstancesPtr EnumInstances;
214 HR = ISetupConfiguration2Ptr(Query)->EnumAllInstances(&EnumInstances);
218 ISetupInstancePtr Instance;
219 HR = EnumInstances->Next(1, &Instance, nullptr);
223 ISetupInstancePtr NewestInstance;
224 Optional<uint64_t> NewestVersionNum;
226 bstr_t VersionString;
228 HR = Instance->GetInstallationVersion(VersionString.GetAddress());
231 HR = ISetupHelperPtr(Query)->ParseVersion(VersionString, &VersionNum);
234 if (!NewestVersionNum || (VersionNum > NewestVersionNum)) {
235 NewestInstance = Instance;
236 NewestVersionNum = VersionNum;
238 } while ((HR = EnumInstances->Next(1, &Instance, nullptr)) == S_OK);
244 HR = NewestInstance->ResolvePath(L"VC", VCPathWide.GetAddress());
248 std::string VCRootPath;
249 llvm::convertWideToUTF8(std::wstring(VCPathWide), VCRootPath);
251 llvm::SmallString<256> ToolsVersionFilePath(VCRootPath);
252 llvm::sys::path::append(ToolsVersionFilePath, "Auxiliary", "Build",
253 "Microsoft.VCToolsVersion.default.txt");
255 auto ToolsVersionFile = llvm::MemoryBuffer::getFile(ToolsVersionFilePath);
256 if (!ToolsVersionFile)
259 llvm::SmallString<256> ToolchainPath(VCRootPath);
260 llvm::sys::path::append(ToolchainPath, "Tools", "MSVC",
261 ToolsVersionFile->get()->getBuffer().rtrim());
262 if (!llvm::sys::fs::is_directory(ToolchainPath))
265 Path = ToolchainPath.str();
266 IsVS2017OrNewer = true;
271 // Look in the registry for Visual Studio installs, and use that to get
272 // a toolchain path. VS2017 and newer don't get added to the registry.
273 // So if we find something here, we know that it's an older version.
274 static bool findVCToolChainViaRegistry(std::string &Path,
275 bool &IsVS2017OrNewer) {
276 std::string VSInstallPath;
277 if (getSystemRegistryString(R"(SOFTWARE\Microsoft\VisualStudio\$VERSION)",
278 "InstallDir", VSInstallPath, nullptr) ||
279 getSystemRegistryString(R"(SOFTWARE\Microsoft\VCExpress\$VERSION)",
280 "InstallDir", VSInstallPath, nullptr)) {
281 if (!VSInstallPath.empty()) {
282 llvm::SmallString<256> VCPath(llvm::StringRef(
283 VSInstallPath.c_str(), VSInstallPath.find(R"(\Common7\IDE)")));
284 llvm::sys::path::append(VCPath, "VC");
287 IsVS2017OrNewer = false;
294 // Try to find Exe from a Visual Studio distribution. This first tries to find
295 // an installed copy of Visual Studio and, failing that, looks in the PATH,
296 // making sure that whatever executable that's found is not a same-named exe
297 // from clang itself to prevent clang from falling back to itself.
298 static std::string FindVisualStudioExecutable(const ToolChain &TC,
300 const auto &MSVC = static_cast<const toolchains::MSVCToolChain &>(TC);
301 SmallString<128> FilePath(MSVC.getSubDirectoryPath(
302 toolchains::MSVCToolChain::SubDirectoryType::Bin));
303 llvm::sys::path::append(FilePath, Exe);
304 return llvm::sys::fs::can_execute(FilePath) ? FilePath.str() : Exe;
307 void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA,
308 const InputInfo &Output,
309 const InputInfoList &Inputs,
311 const char *LinkingOutput) const {
312 ArgStringList CmdArgs;
314 auto &TC = static_cast<const toolchains::MSVCToolChain &>(getToolChain());
316 assert((Output.isFilename() || Output.isNothing()) && "invalid output");
317 if (Output.isFilename())
319 Args.MakeArgString(std::string("-out:") + Output.getFilename()));
321 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles) &&
322 !C.getDriver().IsCLMode())
323 CmdArgs.push_back("-defaultlib:libcmt");
325 if (!llvm::sys::Process::GetEnv("LIB")) {
326 // If the VC environment hasn't been configured (perhaps because the user
327 // did not run vcvarsall), try to build a consistent link environment. If
328 // the environment variable is set however, assume the user knows what
330 CmdArgs.push_back(Args.MakeArgString(
332 TC.getSubDirectoryPath(
333 toolchains::MSVCToolChain::SubDirectoryType::Lib)));
335 if (TC.useUniversalCRT()) {
336 std::string UniversalCRTLibPath;
337 if (TC.getUniversalCRTLibraryPath(UniversalCRTLibPath))
339 Args.MakeArgString(Twine("-libpath:") + UniversalCRTLibPath));
342 std::string WindowsSdkLibPath;
343 if (TC.getWindowsSDKLibraryPath(WindowsSdkLibPath))
345 Args.MakeArgString(std::string("-libpath:") + WindowsSdkLibPath));
348 if (!C.getDriver().IsCLMode() && Args.hasArg(options::OPT_L))
349 for (const auto &LibPath : Args.getAllArgValues(options::OPT_L))
350 CmdArgs.push_back(Args.MakeArgString("-libpath:" + LibPath));
352 CmdArgs.push_back("-nologo");
354 if (Args.hasArg(options::OPT_g_Group, options::OPT__SLASH_Z7,
355 options::OPT__SLASH_Zd))
356 CmdArgs.push_back("-debug");
358 bool DLL = Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd,
359 options::OPT_shared);
361 CmdArgs.push_back(Args.MakeArgString("-dll"));
363 SmallString<128> ImplibName(Output.getFilename());
364 llvm::sys::path::replace_extension(ImplibName, "lib");
365 CmdArgs.push_back(Args.MakeArgString(std::string("-implib:") + ImplibName));
368 if (TC.getSanitizerArgs().needsAsanRt()) {
369 CmdArgs.push_back(Args.MakeArgString("-debug"));
370 CmdArgs.push_back(Args.MakeArgString("-incremental:no"));
371 if (TC.getSanitizerArgs().needsSharedAsanRt() ||
372 Args.hasArg(options::OPT__SLASH_MD, options::OPT__SLASH_MDd)) {
373 for (const auto &Lib : {"asan_dynamic", "asan_dynamic_runtime_thunk"})
374 CmdArgs.push_back(TC.getCompilerRTArgString(Args, Lib));
375 // Make sure the dynamic runtime thunk is not optimized out at link time
376 // to ensure proper SEH handling.
377 CmdArgs.push_back(Args.MakeArgString(
378 TC.getArch() == llvm::Triple::x86
379 ? "-include:___asan_seh_interceptor"
380 : "-include:__asan_seh_interceptor"));
381 // Make sure the linker consider all object files from the dynamic runtime
383 CmdArgs.push_back(Args.MakeArgString(std::string("-wholearchive:") +
384 TC.getCompilerRT(Args, "asan_dynamic_runtime_thunk")));
386 CmdArgs.push_back(TC.getCompilerRTArgString(Args, "asan_dll_thunk"));
388 for (const auto &Lib : {"asan", "asan_cxx"}) {
389 CmdArgs.push_back(TC.getCompilerRTArgString(Args, Lib));
390 // Make sure the linker consider all object files from the static lib.
391 // This is necessary because instrumented dlls need access to all the
392 // interface exported by the static lib in the main executable.
393 CmdArgs.push_back(Args.MakeArgString(std::string("-wholearchive:") +
394 TC.getCompilerRT(Args, Lib)));
399 Args.AddAllArgValues(CmdArgs, options::OPT__SLASH_link);
401 if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
402 options::OPT_fno_openmp, false)) {
403 CmdArgs.push_back("-nodefaultlib:vcomp.lib");
404 CmdArgs.push_back("-nodefaultlib:vcompd.lib");
405 CmdArgs.push_back(Args.MakeArgString(std::string("-libpath:") +
406 TC.getDriver().Dir + "/../lib"));
407 switch (TC.getDriver().getOpenMPRuntime(Args)) {
408 case Driver::OMPRT_OMP:
409 CmdArgs.push_back("-defaultlib:libomp.lib");
411 case Driver::OMPRT_IOMP5:
412 CmdArgs.push_back("-defaultlib:libiomp5md.lib");
414 case Driver::OMPRT_GOMP:
416 case Driver::OMPRT_Unknown:
417 // Already diagnosed.
422 // Add compiler-rt lib in case if it was explicitly
423 // specified as an argument for --rtlib option.
424 if (!Args.hasArg(options::OPT_nostdlib)) {
425 AddRunTimeLibs(TC, TC.getDriver(), CmdArgs, Args);
428 // Add filenames, libraries, and other linker inputs.
429 for (const auto &Input : Inputs) {
430 if (Input.isFilename()) {
431 CmdArgs.push_back(Input.getFilename());
435 const Arg &A = Input.getInputArg();
437 // Render -l options differently for the MSVC linker.
438 if (A.getOption().matches(options::OPT_l)) {
439 StringRef Lib = A.getValue();
440 const char *LinkLibArg;
441 if (Lib.endswith(".lib"))
442 LinkLibArg = Args.MakeArgString(Lib);
444 LinkLibArg = Args.MakeArgString(Lib + ".lib");
445 CmdArgs.push_back(LinkLibArg);
449 // Otherwise, this is some other kind of linker input option like -Wl, -z,
450 // or -L. Render it, even if MSVC doesn't understand it.
451 A.renderAsInput(Args, CmdArgs);
454 TC.addProfileRTLibs(Args, CmdArgs);
456 std::vector<const char *> Environment;
458 // We need to special case some linker paths. In the case of lld, we need to
459 // translate 'lld' into 'lld-link', and in the case of the regular msvc
460 // linker, we need to use a special search algorithm.
461 llvm::SmallString<128> linkPath;
462 StringRef Linker = Args.getLastArgValue(options::OPT_fuse_ld_EQ, "link");
463 if (Linker.equals_lower("lld"))
466 if (Linker.equals_lower("link")) {
467 // If we're using the MSVC linker, it's not sufficient to just use link
468 // from the program PATH, because other environments like GnuWin32 install
469 // their own link.exe which may come first.
470 linkPath = FindVisualStudioExecutable(TC, "link.exe");
473 // When cross-compiling with VS2017 or newer, link.exe expects to have
474 // its containing bin directory at the top of PATH, followed by the
475 // native target bin directory.
476 // e.g. when compiling for x86 on an x64 host, PATH should start with:
477 // /bin/HostX64/x86;/bin/HostX64/x64
478 if (TC.getIsVS2017OrNewer() &&
479 llvm::Triple(llvm::sys::getProcessTriple()).getArch() != TC.getArch()) {
480 auto HostArch = llvm::Triple(llvm::sys::getProcessTriple()).getArch();
483 std::unique_ptr<wchar_t[], decltype(&FreeEnvironmentStringsW)>(
484 GetEnvironmentStringsW(), FreeEnvironmentStringsW);
486 goto SkipSettingEnvironment;
489 size_t EnvBlockLen = 0;
490 while (EnvBlockWide[EnvBlockLen] != L'\0') {
492 EnvBlockLen += std::wcslen(&EnvBlockWide[EnvBlockLen]) +
493 1 /*string null-terminator*/;
495 ++EnvBlockLen; // add the block null-terminator
497 std::string EnvBlock;
498 if (!llvm::convertUTF16ToUTF8String(
499 llvm::ArrayRef<char>(reinterpret_cast<char *>(EnvBlockWide.get()),
500 EnvBlockLen * sizeof(EnvBlockWide[0])),
502 goto SkipSettingEnvironment;
504 Environment.reserve(EnvCount);
506 // Now loop over each string in the block and copy them into the
507 // environment vector, adjusting the PATH variable as needed when we
509 for (const char *Cursor = EnvBlock.data(); *Cursor != '\0';) {
510 llvm::StringRef EnvVar(Cursor);
511 if (EnvVar.startswith_lower("path=")) {
512 using SubDirectoryType = toolchains::MSVCToolChain::SubDirectoryType;
513 constexpr size_t PrefixLen = 5; // strlen("path=")
514 Environment.push_back(Args.MakeArgString(
515 EnvVar.substr(0, PrefixLen) +
516 TC.getSubDirectoryPath(SubDirectoryType::Bin) +
517 llvm::Twine(llvm::sys::EnvPathSeparator) +
518 TC.getSubDirectoryPath(SubDirectoryType::Bin, HostArch) +
519 (EnvVar.size() > PrefixLen
520 ? llvm::Twine(llvm::sys::EnvPathSeparator) +
521 EnvVar.substr(PrefixLen)
524 Environment.push_back(Args.MakeArgString(EnvVar));
526 Cursor += EnvVar.size() + 1 /*null-terminator*/;
529 SkipSettingEnvironment:;
533 llvm::sys::path::replace_extension(linkPath, "exe");
534 linkPath = TC.GetProgramPath(linkPath.c_str());
537 auto LinkCmd = llvm::make_unique<Command>(
538 JA, *this, Args.MakeArgString(linkPath), CmdArgs, Inputs);
539 if (!Environment.empty())
540 LinkCmd->setEnvironment(Environment);
541 C.addCommand(std::move(LinkCmd));
544 void visualstudio::Compiler::ConstructJob(Compilation &C, const JobAction &JA,
545 const InputInfo &Output,
546 const InputInfoList &Inputs,
548 const char *LinkingOutput) const {
549 C.addCommand(GetCommand(C, JA, Output, Inputs, Args, LinkingOutput));
552 std::unique_ptr<Command> visualstudio::Compiler::GetCommand(
553 Compilation &C, const JobAction &JA, const InputInfo &Output,
554 const InputInfoList &Inputs, const ArgList &Args,
555 const char *LinkingOutput) const {
556 ArgStringList CmdArgs;
557 CmdArgs.push_back("/nologo");
558 CmdArgs.push_back("/c"); // Compile only.
559 CmdArgs.push_back("/W0"); // No warnings.
561 // The goal is to be able to invoke this tool correctly based on
562 // any flag accepted by clang-cl.
564 // These are spelled the same way in clang and cl.exe,.
565 Args.AddAllArgs(CmdArgs, {options::OPT_D, options::OPT_U, options::OPT_I});
567 // Optimization level.
568 if (Arg *A = Args.getLastArg(options::OPT_fbuiltin, options::OPT_fno_builtin))
569 CmdArgs.push_back(A->getOption().getID() == options::OPT_fbuiltin ? "/Oi"
571 if (Arg *A = Args.getLastArg(options::OPT_O, options::OPT_O0)) {
572 if (A->getOption().getID() == options::OPT_O0) {
573 CmdArgs.push_back("/Od");
575 CmdArgs.push_back("/Og");
577 StringRef OptLevel = A->getValue();
578 if (OptLevel == "s" || OptLevel == "z")
579 CmdArgs.push_back("/Os");
581 CmdArgs.push_back("/Ot");
583 CmdArgs.push_back("/Ob2");
586 if (Arg *A = Args.getLastArg(options::OPT_fomit_frame_pointer,
587 options::OPT_fno_omit_frame_pointer))
588 CmdArgs.push_back(A->getOption().getID() == options::OPT_fomit_frame_pointer
591 if (!Args.hasArg(options::OPT_fwritable_strings))
592 CmdArgs.push_back("/GF");
594 // Flags for which clang-cl has an alias.
595 // FIXME: How can we ensure this stays in sync with relevant clang-cl options?
597 if (Args.hasFlag(options::OPT__SLASH_GR_, options::OPT__SLASH_GR,
599 CmdArgs.push_back("/GR-");
601 if (Args.hasFlag(options::OPT__SLASH_GS_, options::OPT__SLASH_GS,
603 CmdArgs.push_back("/GS-");
605 if (Arg *A = Args.getLastArg(options::OPT_ffunction_sections,
606 options::OPT_fno_function_sections))
607 CmdArgs.push_back(A->getOption().getID() == options::OPT_ffunction_sections
610 if (Arg *A = Args.getLastArg(options::OPT_fdata_sections,
611 options::OPT_fno_data_sections))
613 A->getOption().getID() == options::OPT_fdata_sections ? "/Gw" : "/Gw-");
614 if (Args.hasArg(options::OPT_fsyntax_only))
615 CmdArgs.push_back("/Zs");
616 if (Args.hasArg(options::OPT_g_Flag, options::OPT_gline_tables_only,
617 options::OPT__SLASH_Z7))
618 CmdArgs.push_back("/Z7");
620 std::vector<std::string> Includes =
621 Args.getAllArgValues(options::OPT_include);
622 for (const auto &Include : Includes)
623 CmdArgs.push_back(Args.MakeArgString(std::string("/FI") + Include));
625 // Flags that can simply be passed through.
626 Args.AddAllArgs(CmdArgs, options::OPT__SLASH_LD);
627 Args.AddAllArgs(CmdArgs, options::OPT__SLASH_LDd);
628 Args.AddAllArgs(CmdArgs, options::OPT__SLASH_GX);
629 Args.AddAllArgs(CmdArgs, options::OPT__SLASH_GX_);
630 Args.AddAllArgs(CmdArgs, options::OPT__SLASH_EH);
631 Args.AddAllArgs(CmdArgs, options::OPT__SLASH_Zl);
633 // The order of these flags is relevant, so pick the last one.
634 if (Arg *A = Args.getLastArg(options::OPT__SLASH_MD, options::OPT__SLASH_MDd,
635 options::OPT__SLASH_MT, options::OPT__SLASH_MTd))
636 A->render(Args, CmdArgs);
638 // Use MSVC's default threadsafe statics behaviour unless there was a flag.
639 if (Arg *A = Args.getLastArg(options::OPT_fthreadsafe_statics,
640 options::OPT_fno_threadsafe_statics)) {
641 CmdArgs.push_back(A->getOption().getID() == options::OPT_fthreadsafe_statics
642 ? "/Zc:threadSafeInit"
643 : "/Zc:threadSafeInit-");
646 // Pass through all unknown arguments so that the fallback command can see
648 Args.AddAllArgs(CmdArgs, options::OPT_UNKNOWN);
651 assert(Inputs.size() == 1);
652 const InputInfo &II = Inputs[0];
653 assert(II.getType() == types::TY_C || II.getType() == types::TY_CXX);
654 CmdArgs.push_back(II.getType() == types::TY_C ? "/Tc" : "/Tp");
656 CmdArgs.push_back(II.getFilename());
658 II.getInputArg().renderAsInput(Args, CmdArgs);
661 assert(Output.getType() == types::TY_Object);
663 Args.MakeArgString(std::string("/Fo") + Output.getFilename());
664 CmdArgs.push_back(Fo);
666 std::string Exec = FindVisualStudioExecutable(getToolChain(), "cl.exe");
667 return llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Exec),
671 MSVCToolChain::MSVCToolChain(const Driver &D, const llvm::Triple &Triple,
673 : ToolChain(D, Triple, Args), CudaInstallation(D, Triple, Args) {
674 getProgramPaths().push_back(getDriver().getInstalledDir());
675 if (getDriver().getInstalledDir() != getDriver().Dir)
676 getProgramPaths().push_back(getDriver().Dir);
678 // Check the environment first, since that's probably the user telling us
679 // what they want to use.
680 // Failing that, just try to find the newest Visual Studio version we can
681 // and use its default VC toolchain.
682 findVCToolChainViaEnvironment(VCToolChainPath, IsVS2017OrNewer) ||
683 findVCToolChainViaSetupConfig(VCToolChainPath, IsVS2017OrNewer) ||
684 findVCToolChainViaRegistry(VCToolChainPath, IsVS2017OrNewer);
687 Tool *MSVCToolChain::buildLinker() const {
688 if (VCToolChainPath.empty())
689 getDriver().Diag(clang::diag::warn_drv_msvc_not_found);
690 return new tools::visualstudio::Linker(*this);
693 Tool *MSVCToolChain::buildAssembler() const {
694 if (getTriple().isOSBinFormatMachO())
695 return new tools::darwin::Assembler(*this);
696 getDriver().Diag(clang::diag::err_no_external_assembler);
700 bool MSVCToolChain::IsIntegratedAssemblerDefault() const {
704 bool MSVCToolChain::IsUnwindTablesDefault() const {
705 // Emit unwind tables by default on Win64. All non-x86_32 Windows platforms
706 // such as ARM and PPC actually require unwind tables, but LLVM doesn't know
707 // how to generate them yet.
709 // Don't emit unwind tables by default for MachO targets.
710 if (getTriple().isOSBinFormatMachO())
713 return getArch() == llvm::Triple::x86_64;
716 bool MSVCToolChain::isPICDefault() const {
717 return getArch() == llvm::Triple::x86_64;
720 bool MSVCToolChain::isPIEDefault() const {
724 bool MSVCToolChain::isPICDefaultForced() const {
725 return getArch() == llvm::Triple::x86_64;
728 void MSVCToolChain::AddCudaIncludeArgs(const ArgList &DriverArgs,
729 ArgStringList &CC1Args) const {
730 CudaInstallation.AddCudaIncludeArgs(DriverArgs, CC1Args);
733 void MSVCToolChain::printVerboseInfo(raw_ostream &OS) const {
734 CudaInstallation.print(OS);
737 // Windows SDKs and VC Toolchains group their contents into subdirectories based
738 // on the target architecture. This function converts an llvm::Triple::ArchType
739 // to the corresponding subdirectory name.
740 static const char *llvmArchToWindowsSDKArch(llvm::Triple::ArchType Arch) {
741 using ArchType = llvm::Triple::ArchType;
745 case ArchType::x86_64:
754 // Similar to the above function, but for Visual Studios before VS2017.
755 static const char *llvmArchToLegacyVCArch(llvm::Triple::ArchType Arch) {
756 using ArchType = llvm::Triple::ArchType;
759 // x86 is default in legacy VC toolchains.
760 // e.g. x86 libs are directly in /lib as opposed to /lib/x86.
762 case ArchType::x86_64:
771 // Get the path to a specific subdirectory in the current toolchain for
772 // a given target architecture.
773 // VS2017 changed the VC toolchain layout, so this should be used instead
774 // of hardcoding paths.
776 MSVCToolChain::getSubDirectoryPath(SubDirectoryType Type,
777 llvm::Triple::ArchType TargetArch) const {
778 llvm::SmallString<256> Path(VCToolChainPath);
780 case SubDirectoryType::Bin:
781 if (IsVS2017OrNewer) {
783 llvm::Triple(llvm::sys::getProcessTriple()).isArch64Bit();
784 llvm::sys::path::append(Path, "bin", (HostIsX64 ? "HostX64" : "HostX86"),
785 llvmArchToWindowsSDKArch(TargetArch));
788 llvm::sys::path::append(Path, "bin", llvmArchToLegacyVCArch(TargetArch));
791 case SubDirectoryType::Include:
792 llvm::sys::path::append(Path, "include");
794 case SubDirectoryType::Lib:
795 llvm::sys::path::append(
796 Path, "lib", IsVS2017OrNewer ? llvmArchToWindowsSDKArch(TargetArch)
797 : llvmArchToLegacyVCArch(TargetArch));
804 static bool readFullStringValue(HKEY hkey, const char *valueName,
805 std::string &value) {
806 std::wstring WideValueName;
807 if (!llvm::ConvertUTF8toWide(valueName, WideValueName))
813 // First just query for the required size.
814 result = RegQueryValueExW(hkey, WideValueName.c_str(), NULL, &type, NULL,
816 if (result != ERROR_SUCCESS || type != REG_SZ || !valueSize)
818 std::vector<BYTE> buffer(valueSize);
819 result = RegQueryValueExW(hkey, WideValueName.c_str(), NULL, NULL, &buffer[0],
821 if (result == ERROR_SUCCESS) {
822 std::wstring WideValue(reinterpret_cast<const wchar_t *>(buffer.data()),
823 valueSize / sizeof(wchar_t));
824 if (valueSize && WideValue.back() == L'\0') {
825 WideValue.pop_back();
827 // The destination buffer must be empty as an invariant of the conversion
828 // function; but this function is sometimes called in a loop that passes in
829 // the same buffer, however. Simply clear it out so we can overwrite it.
831 return llvm::convertWideToUTF8(WideValue, value);
837 /// \brief Read registry string.
838 /// This also supports a means to look for high-versioned keys by use
839 /// of a $VERSION placeholder in the key path.
840 /// $VERSION in the key path is a placeholder for the version number,
841 /// causing the highest value path to be searched for and used.
842 /// I.e. "SOFTWARE\\Microsoft\\VisualStudio\\$VERSION".
843 /// There can be additional characters in the component. Only the numeric
844 /// characters are compared. This function only searches HKLM.
845 static bool getSystemRegistryString(const char *keyPath, const char *valueName,
846 std::string &value, std::string *phValue) {
850 HKEY hRootKey = HKEY_LOCAL_MACHINE;
853 bool returnValue = false;
855 const char *placeHolder = strstr(keyPath, "$VERSION");
856 std::string bestName;
857 // If we have a $VERSION placeholder, do the highest-version search.
859 const char *keyEnd = placeHolder - 1;
860 const char *nextKey = placeHolder;
861 // Find end of previous key.
862 while ((keyEnd > keyPath) && (*keyEnd != '\\'))
864 // Find end of key containing $VERSION.
865 while (*nextKey && (*nextKey != '\\'))
867 size_t partialKeyLength = keyEnd - keyPath;
868 char partialKey[256];
869 if (partialKeyLength >= sizeof(partialKey))
870 partialKeyLength = sizeof(partialKey) - 1;
871 strncpy(partialKey, keyPath, partialKeyLength);
872 partialKey[partialKeyLength] = '\0';
874 lResult = RegOpenKeyExA(hRootKey, partialKey, 0, KEY_READ | KEY_WOW64_32KEY,
876 if (lResult == ERROR_SUCCESS) {
878 double bestValue = 0.0;
879 DWORD index, size = sizeof(keyName) - 1;
880 for (index = 0; RegEnumKeyExA(hTopKey, index, keyName, &size, NULL, NULL,
881 NULL, NULL) == ERROR_SUCCESS;
883 const char *sp = keyName;
884 while (*sp && !isDigit(*sp))
888 const char *ep = sp + 1;
889 while (*ep && (isDigit(*ep) || (*ep == '.')))
892 strncpy(numBuf, sp, sizeof(numBuf) - 1);
893 numBuf[sizeof(numBuf) - 1] = '\0';
894 double dvalue = strtod(numBuf, NULL);
895 if (dvalue > bestValue) {
896 // Test that InstallDir is indeed there before keeping this index.
897 // Open the chosen key path remainder.
899 // Append rest of key.
900 bestName.append(nextKey);
901 lResult = RegOpenKeyExA(hTopKey, bestName.c_str(), 0,
902 KEY_READ | KEY_WOW64_32KEY, &hKey);
903 if (lResult == ERROR_SUCCESS) {
904 if (readFullStringValue(hKey, valueName, value)) {
913 size = sizeof(keyName) - 1;
915 RegCloseKey(hTopKey);
919 RegOpenKeyExA(hRootKey, keyPath, 0, KEY_READ | KEY_WOW64_32KEY, &hKey);
920 if (lResult == ERROR_SUCCESS) {
921 if (readFullStringValue(hKey, valueName, value))
932 // Find the most recent version of Universal CRT or Windows 10 SDK.
933 // vcvarsqueryregistry.bat from Visual Studio 2015 sorts entries in the include
934 // directory by name and uses the last one of the list.
935 // So we compare entry names lexicographically to find the greatest one.
936 static bool getWindows10SDKVersionFromPath(const std::string &SDKPath,
937 std::string &SDKVersion) {
941 llvm::SmallString<128> IncludePath(SDKPath);
942 llvm::sys::path::append(IncludePath, "Include");
943 for (llvm::sys::fs::directory_iterator DirIt(IncludePath, EC), DirEnd;
944 DirIt != DirEnd && !EC; DirIt.increment(EC)) {
945 if (!llvm::sys::fs::is_directory(DirIt->path()))
947 StringRef CandidateName = llvm::sys::path::filename(DirIt->path());
948 // If WDK is installed, there could be subfolders like "wdf" in the
949 // "Include" directory.
950 // Allow only directories which names start with "10.".
951 if (!CandidateName.startswith("10."))
953 if (CandidateName > SDKVersion)
954 SDKVersion = CandidateName;
957 return !SDKVersion.empty();
960 /// \brief Get Windows SDK installation directory.
961 static bool getWindowsSDKDir(std::string &Path, int &Major,
962 std::string &WindowsSDKIncludeVersion,
963 std::string &WindowsSDKLibVersion) {
964 std::string RegistrySDKVersion;
965 // Try the Windows registry.
966 if (!getSystemRegistryString(
967 "SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\$VERSION",
968 "InstallationFolder", Path, &RegistrySDKVersion))
970 if (Path.empty() || RegistrySDKVersion.empty())
973 WindowsSDKIncludeVersion.clear();
974 WindowsSDKLibVersion.clear();
976 std::sscanf(RegistrySDKVersion.c_str(), "v%d.", &Major);
980 // Windows SDK 8.x installs libraries in a folder whose names depend on the
981 // version of the OS you're targeting. By default choose the newest, which
982 // usually corresponds to the version of the OS you've installed the SDK on.
983 const char *Tests[] = {"winv6.3", "win8", "win7"};
984 for (const char *Test : Tests) {
985 llvm::SmallString<128> TestPath(Path);
986 llvm::sys::path::append(TestPath, "Lib", Test);
987 if (llvm::sys::fs::exists(TestPath.c_str())) {
988 WindowsSDKLibVersion = Test;
992 return !WindowsSDKLibVersion.empty();
995 if (!getWindows10SDKVersionFromPath(Path, WindowsSDKIncludeVersion))
997 WindowsSDKLibVersion = WindowsSDKIncludeVersion;
1000 // Unsupported SDK version
1004 // Gets the library path required to link against the Windows SDK.
1005 bool MSVCToolChain::getWindowsSDKLibraryPath(std::string &path) const {
1006 std::string sdkPath;
1008 std::string windowsSDKIncludeVersion;
1009 std::string windowsSDKLibVersion;
1012 if (!getWindowsSDKDir(sdkPath, sdkMajor, windowsSDKIncludeVersion,
1013 windowsSDKLibVersion))
1016 llvm::SmallString<128> libPath(sdkPath);
1017 llvm::sys::path::append(libPath, "Lib");
1018 if (sdkMajor >= 8) {
1019 llvm::sys::path::append(libPath, windowsSDKLibVersion, "um",
1020 llvmArchToWindowsSDKArch(getArch()));
1022 switch (getArch()) {
1023 // In Windows SDK 7.x, x86 libraries are directly in the Lib folder.
1024 case llvm::Triple::x86:
1026 case llvm::Triple::x86_64:
1027 llvm::sys::path::append(libPath, "x64");
1029 case llvm::Triple::arm:
1030 // It is not necessary to link against Windows SDK 7.x when targeting ARM.
1037 path = libPath.str();
1041 // Check if the Include path of a specified version of Visual Studio contains
1042 // specific header files. If not, they are probably shipped with Universal CRT.
1043 bool MSVCToolChain::useUniversalCRT() const {
1044 llvm::SmallString<128> TestPath(
1045 getSubDirectoryPath(SubDirectoryType::Include));
1046 llvm::sys::path::append(TestPath, "stdlib.h");
1047 return !llvm::sys::fs::exists(TestPath);
1050 static bool getUniversalCRTSdkDir(std::string &Path, std::string &UCRTVersion) {
1051 // vcvarsqueryregistry.bat for Visual Studio 2015 queries the registry
1052 // for the specific key "KitsRoot10". So do we.
1053 if (!getSystemRegistryString(
1054 "SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots", "KitsRoot10",
1058 return getWindows10SDKVersionFromPath(Path, UCRTVersion);
1061 bool MSVCToolChain::getUniversalCRTLibraryPath(std::string &Path) const {
1062 std::string UniversalCRTSdkPath;
1063 std::string UCRTVersion;
1066 if (!getUniversalCRTSdkDir(UniversalCRTSdkPath, UCRTVersion))
1069 StringRef ArchName = llvmArchToWindowsSDKArch(getArch());
1070 if (ArchName.empty())
1073 llvm::SmallString<128> LibPath(UniversalCRTSdkPath);
1074 llvm::sys::path::append(LibPath, "Lib", UCRTVersion, "ucrt", ArchName);
1076 Path = LibPath.str();
1080 static VersionTuple getMSVCVersionFromTriple(const llvm::Triple &Triple) {
1081 unsigned Major, Minor, Micro;
1082 Triple.getEnvironmentVersion(Major, Minor, Micro);
1083 if (Major || Minor || Micro)
1084 return VersionTuple(Major, Minor, Micro);
1085 return VersionTuple();
1088 static VersionTuple getMSVCVersionFromExe(const std::string &BinDir) {
1089 VersionTuple Version;
1091 SmallString<128> ClExe(BinDir);
1092 llvm::sys::path::append(ClExe, "cl.exe");
1094 std::wstring ClExeWide;
1095 if (!llvm::ConvertUTF8toWide(ClExe.c_str(), ClExeWide))
1098 const DWORD VersionSize = ::GetFileVersionInfoSizeW(ClExeWide.c_str(),
1100 if (VersionSize == 0)
1103 SmallVector<uint8_t, 4 * 1024> VersionBlock(VersionSize);
1104 if (!::GetFileVersionInfoW(ClExeWide.c_str(), 0, VersionSize,
1105 VersionBlock.data()))
1108 VS_FIXEDFILEINFO *FileInfo = nullptr;
1109 UINT FileInfoSize = 0;
1110 if (!::VerQueryValueW(VersionBlock.data(), L"\\",
1111 reinterpret_cast<LPVOID *>(&FileInfo), &FileInfoSize) ||
1112 FileInfoSize < sizeof(*FileInfo))
1115 const unsigned Major = (FileInfo->dwFileVersionMS >> 16) & 0xFFFF;
1116 const unsigned Minor = (FileInfo->dwFileVersionMS ) & 0xFFFF;
1117 const unsigned Micro = (FileInfo->dwFileVersionLS >> 16) & 0xFFFF;
1119 Version = VersionTuple(Major, Minor, Micro);
1124 void MSVCToolChain::AddSystemIncludeWithSubfolder(
1125 const ArgList &DriverArgs, ArgStringList &CC1Args,
1126 const std::string &folder, const Twine &subfolder1, const Twine &subfolder2,
1127 const Twine &subfolder3) const {
1128 llvm::SmallString<128> path(folder);
1129 llvm::sys::path::append(path, subfolder1, subfolder2, subfolder3);
1130 addSystemInclude(DriverArgs, CC1Args, path);
1133 void MSVCToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
1134 ArgStringList &CC1Args) const {
1135 if (DriverArgs.hasArg(options::OPT_nostdinc))
1138 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
1139 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, getDriver().ResourceDir,
1143 // Add %INCLUDE%-like directories from the -imsvc flag.
1144 for (const auto &Path : DriverArgs.getAllArgValues(options::OPT__SLASH_imsvc))
1145 addSystemInclude(DriverArgs, CC1Args, Path);
1147 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
1150 // Honor %INCLUDE%. It should know essential search paths with vcvarsall.bat.
1151 if (llvm::Optional<std::string> cl_include_dir =
1152 llvm::sys::Process::GetEnv("INCLUDE")) {
1153 SmallVector<StringRef, 8> Dirs;
1154 StringRef(*cl_include_dir)
1155 .split(Dirs, ";", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
1156 for (StringRef Dir : Dirs)
1157 addSystemInclude(DriverArgs, CC1Args, Dir);
1162 // When built with access to the proper Windows APIs, try to actually find
1163 // the correct include paths first.
1164 if (!VCToolChainPath.empty()) {
1165 addSystemInclude(DriverArgs, CC1Args,
1166 getSubDirectoryPath(SubDirectoryType::Include));
1168 if (useUniversalCRT()) {
1169 std::string UniversalCRTSdkPath;
1170 std::string UCRTVersion;
1171 if (getUniversalCRTSdkDir(UniversalCRTSdkPath, UCRTVersion)) {
1172 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, UniversalCRTSdkPath,
1173 "Include", UCRTVersion, "ucrt");
1177 std::string WindowsSDKDir;
1179 std::string windowsSDKIncludeVersion;
1180 std::string windowsSDKLibVersion;
1181 if (getWindowsSDKDir(WindowsSDKDir, major, windowsSDKIncludeVersion,
1182 windowsSDKLibVersion)) {
1184 // Note: windowsSDKIncludeVersion is empty for SDKs prior to v10.
1185 // Anyway, llvm::sys::path::append is able to manage it.
1186 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
1187 "include", windowsSDKIncludeVersion,
1189 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
1190 "include", windowsSDKIncludeVersion,
1192 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
1193 "include", windowsSDKIncludeVersion,
1196 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
1204 #if defined(LLVM_ON_WIN32)
1205 // As a fallback, select default install paths.
1206 // FIXME: Don't guess drives and paths like this on Windows.
1207 const StringRef Paths[] = {
1208 "C:/Program Files/Microsoft Visual Studio 10.0/VC/include",
1209 "C:/Program Files/Microsoft Visual Studio 9.0/VC/include",
1210 "C:/Program Files/Microsoft Visual Studio 9.0/VC/PlatformSDK/Include",
1211 "C:/Program Files/Microsoft Visual Studio 8/VC/include",
1212 "C:/Program Files/Microsoft Visual Studio 8/VC/PlatformSDK/Include"
1214 addSystemIncludes(DriverArgs, CC1Args, Paths);
1218 void MSVCToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
1219 ArgStringList &CC1Args) const {
1220 // FIXME: There should probably be logic here to find libc++ on Windows.
1223 VersionTuple MSVCToolChain::computeMSVCVersion(const Driver *D,
1224 const ArgList &Args) const {
1225 bool IsWindowsMSVC = getTriple().isWindowsMSVCEnvironment();
1226 VersionTuple MSVT = ToolChain::computeMSVCVersion(D, Args);
1228 MSVT = getMSVCVersionFromTriple(getTriple());
1229 if (MSVT.empty() && IsWindowsMSVC)
1230 MSVT = getMSVCVersionFromExe(getSubDirectoryPath(SubDirectoryType::Bin));
1232 Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions,
1234 // -fms-compatibility-version=18.00 is default.
1235 // FIXME: Consider bumping this to 19 (MSVC2015) soon.
1236 MSVT = VersionTuple(18);
1242 MSVCToolChain::ComputeEffectiveClangTriple(const ArgList &Args,
1243 types::ID InputType) const {
1244 // The MSVC version doesn't care about the architecture, even though it
1245 // may look at the triple internally.
1246 VersionTuple MSVT = computeMSVCVersion(/*D=*/nullptr, Args);
1247 MSVT = VersionTuple(MSVT.getMajor(), MSVT.getMinor().getValueOr(0),
1248 MSVT.getSubminor().getValueOr(0));
1250 // For the rest of the triple, however, a computed architecture name may
1252 llvm::Triple Triple(ToolChain::ComputeEffectiveClangTriple(Args, InputType));
1253 if (Triple.getEnvironment() == llvm::Triple::MSVC) {
1254 StringRef ObjFmt = Triple.getEnvironmentName().split('-').second;
1256 Triple.setEnvironmentName((Twine("msvc") + MSVT.getAsString()).str());
1258 Triple.setEnvironmentName(
1259 (Twine("msvc") + MSVT.getAsString() + Twine('-') + ObjFmt).str());
1261 return Triple.getTriple();
1264 SanitizerMask MSVCToolChain::getSupportedSanitizers() const {
1265 SanitizerMask Res = ToolChain::getSupportedSanitizers();
1266 Res |= SanitizerKind::Address;
1270 static void TranslateOptArg(Arg *A, llvm::opt::DerivedArgList &DAL,
1271 bool SupportsForcingFramePointer,
1272 const char *ExpandChar, const OptTable &Opts) {
1273 assert(A->getOption().matches(options::OPT__SLASH_O));
1275 StringRef OptStr = A->getValue();
1276 for (size_t I = 0, E = OptStr.size(); I != E; ++I) {
1277 const char &OptChar = *(OptStr.data() + I);
1285 if (&OptChar == ExpandChar) {
1286 if (OptChar == 'd') {
1287 DAL.AddFlagArg(A, Opts.getOption(options::OPT_O0));
1289 if (OptChar == '1') {
1290 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "s");
1291 } else if (OptChar == '2' || OptChar == 'x') {
1292 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
1293 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "2");
1295 if (SupportsForcingFramePointer &&
1296 !DAL.hasArgNoClaim(options::OPT_fno_omit_frame_pointer))
1298 Opts.getOption(options::OPT_fomit_frame_pointer));
1299 if (OptChar == '1' || OptChar == '2')
1301 Opts.getOption(options::OPT_ffunction_sections));
1306 if (I + 1 != E && isdigit(OptStr[I + 1])) {
1307 switch (OptStr[I + 1]) {
1309 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_inline));
1312 DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_hint_functions));
1315 DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_functions));
1324 if (I + 1 != E && OptStr[I + 1] == '-') {
1326 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_builtin));
1328 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
1332 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "s");
1335 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "2");
1338 bool OmitFramePointer = true;
1339 if (I + 1 != E && OptStr[I + 1] == '-') {
1340 OmitFramePointer = false;
1343 if (SupportsForcingFramePointer) {
1344 if (OmitFramePointer)
1346 Opts.getOption(options::OPT_fomit_frame_pointer));
1349 A, Opts.getOption(options::OPT_fno_omit_frame_pointer));
1351 // Don't warn about /Oy- in 64-bit builds (where
1352 // SupportsForcingFramePointer is false). The flag having no effect
1353 // there is a compiler-internal optimization, and people shouldn't have
1354 // to special-case their build files for 64-bit clang-cl.
1363 static void TranslateDArg(Arg *A, llvm::opt::DerivedArgList &DAL,
1364 const OptTable &Opts) {
1365 assert(A->getOption().matches(options::OPT_D));
1367 StringRef Val = A->getValue();
1368 size_t Hash = Val.find('#');
1369 if (Hash == StringRef::npos || Hash > Val.find('=')) {
1374 std::string NewVal = Val;
1376 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_D), NewVal);
1379 llvm::opt::DerivedArgList *
1380 MSVCToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args,
1381 StringRef BoundArch, Action::OffloadKind) const {
1382 DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
1383 const OptTable &Opts = getDriver().getOpts();
1385 // /Oy and /Oy- only has an effect under X86-32.
1386 bool SupportsForcingFramePointer = getArch() == llvm::Triple::x86;
1388 // The -O[12xd] flag actually expands to several flags. We must desugar the
1389 // flags so that options embedded can be negated. For example, the '-O2' flag
1390 // enables '-Oy'. Expanding '-O2' into its constituent flags allows us to
1391 // correctly handle '-O2 -Oy-' where the trailing '-Oy-' disables a single
1394 // Note that this expansion logic only applies to the *last* of '[12xd]'.
1396 // First step is to search for the character we'd like to expand.
1397 const char *ExpandChar = nullptr;
1398 for (Arg *A : Args) {
1399 if (!A->getOption().matches(options::OPT__SLASH_O))
1401 StringRef OptStr = A->getValue();
1402 for (size_t I = 0, E = OptStr.size(); I != E; ++I) {
1403 char OptChar = OptStr[I];
1404 char PrevChar = I > 0 ? OptStr[I - 1] : '0';
1405 if (PrevChar == 'b') {
1406 // OptChar does not expand; it's an argument to the previous char.
1409 if (OptChar == '1' || OptChar == '2' || OptChar == 'x' || OptChar == 'd')
1410 ExpandChar = OptStr.data() + I;
1414 for (Arg *A : Args) {
1415 if (A->getOption().matches(options::OPT__SLASH_O)) {
1416 // The -O flag actually takes an amalgam of other options. For example,
1417 // '/Ogyb2' is equivalent to '/Og' '/Oy' '/Ob2'.
1418 TranslateOptArg(A, *DAL, SupportsForcingFramePointer, ExpandChar, Opts);
1419 } else if (A->getOption().matches(options::OPT_D)) {
1420 // Translate -Dfoo#bar into -Dfoo=bar.
1421 TranslateDArg(A, *DAL, Opts);