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 if (llvm::sys::path::filename(PathEntry) == "bin") {
129 llvm::StringRef ParentPath = llvm::sys::path::parent_path(PathEntry);
130 if (llvm::sys::path::filename(ParentPath) == "VC") {
132 IsVS2017OrNewer = false;
137 // This could be a new (>=VS2017) toolchain. If it is, we should find
138 // path components with these prefixes when walking backwards through
140 // Note: empty strings match anything.
141 llvm::StringRef ExpectedPrefixes[] = {"", "Host", "bin", "",
142 "MSVC", "Tools", "VC"};
144 auto It = llvm::sys::path::rbegin(PathEntry);
145 auto End = llvm::sys::path::rend(PathEntry);
146 for (llvm::StringRef Prefix : ExpectedPrefixes) {
149 if (!It->startswith(Prefix))
154 // We've found a new toolchain!
155 // Back up 3 times (/bin/Host/arch) to get the root path.
156 llvm::StringRef ToolChainPath(PathEntry);
157 for (int i = 0; i < 3; ++i)
158 ToolChainPath = llvm::sys::path::parent_path(ToolChainPath);
160 Path = ToolChainPath;
161 IsVS2017OrNewer = true;
172 // Query the Setup Config server for installs, then pick the newest version
173 // and find its default VC toolchain.
174 // This is the preferred way to discover new Visual Studios, as they're no
175 // longer listed in the registry.
176 static bool findVCToolChainViaSetupConfig(std::string &Path,
177 bool &IsVS2017OrNewer) {
178 #if !defined(USE_MSVC_SETUP_API)
181 // FIXME: This really should be done once in the top-level program's main
182 // function, as it may have already been initialized with a different
183 // threading model otherwise.
184 llvm::sys::InitializeCOMRAII COM(llvm::sys::COMThreadingMode::SingleThreaded);
187 // _com_ptr_t will throw a _com_error if a COM calls fail.
188 // The LLVM coding standards forbid exception handling, so we'll have to
189 // stop them from being thrown in the first place.
190 // The destructor will put the regular error handler back when we leave
192 struct SuppressCOMErrorsRAII {
193 static void __stdcall handler(HRESULT hr, IErrorInfo *perrinfo) {}
195 SuppressCOMErrorsRAII() { _set_com_error_handler(handler); }
197 ~SuppressCOMErrorsRAII() { _set_com_error_handler(_com_raise_error); }
199 } COMErrorSuppressor;
201 ISetupConfigurationPtr Query;
202 HR = Query.CreateInstance(__uuidof(SetupConfiguration));
206 IEnumSetupInstancesPtr EnumInstances;
207 HR = ISetupConfiguration2Ptr(Query)->EnumAllInstances(&EnumInstances);
211 ISetupInstancePtr Instance;
212 HR = EnumInstances->Next(1, &Instance, nullptr);
216 ISetupInstancePtr NewestInstance;
217 Optional<uint64_t> NewestVersionNum;
219 bstr_t VersionString;
221 HR = Instance->GetInstallationVersion(VersionString.GetAddress());
224 HR = ISetupHelperPtr(Query)->ParseVersion(VersionString, &VersionNum);
227 if (!NewestVersionNum || (VersionNum > NewestVersionNum)) {
228 NewestInstance = Instance;
229 NewestVersionNum = VersionNum;
231 } while ((HR = EnumInstances->Next(1, &Instance, nullptr)) == S_OK);
237 HR = NewestInstance->ResolvePath(L"VC", VCPathWide.GetAddress());
241 std::string VCRootPath;
242 llvm::convertWideToUTF8(std::wstring(VCPathWide), VCRootPath);
244 llvm::SmallString<256> ToolsVersionFilePath(VCRootPath);
245 llvm::sys::path::append(ToolsVersionFilePath, "Auxiliary", "Build",
246 "Microsoft.VCToolsVersion.default.txt");
248 auto ToolsVersionFile = llvm::MemoryBuffer::getFile(ToolsVersionFilePath);
249 if (!ToolsVersionFile)
252 llvm::SmallString<256> ToolchainPath(VCRootPath);
253 llvm::sys::path::append(ToolchainPath, "Tools", "MSVC",
254 ToolsVersionFile->get()->getBuffer().rtrim());
255 if (!llvm::sys::fs::is_directory(ToolchainPath))
258 Path = ToolchainPath.str();
259 IsVS2017OrNewer = true;
264 // Look in the registry for Visual Studio installs, and use that to get
265 // a toolchain path. VS2017 and newer don't get added to the registry.
266 // So if we find something here, we know that it's an older version.
267 static bool findVCToolChainViaRegistry(std::string &Path,
268 bool &IsVS2017OrNewer) {
269 std::string VSInstallPath;
270 if (getSystemRegistryString(R"(SOFTWARE\Microsoft\VisualStudio\$VERSION)",
271 "InstallDir", VSInstallPath, nullptr) ||
272 getSystemRegistryString(R"(SOFTWARE\Microsoft\VCExpress\$VERSION)",
273 "InstallDir", VSInstallPath, nullptr)) {
274 if (!VSInstallPath.empty()) {
275 llvm::SmallString<256> VCPath(llvm::StringRef(
276 VSInstallPath.c_str(), VSInstallPath.find(R"(\Common7\IDE)")));
277 llvm::sys::path::append(VCPath, "VC");
280 IsVS2017OrNewer = false;
287 // Try to find Exe from a Visual Studio distribution. This first tries to find
288 // an installed copy of Visual Studio and, failing that, looks in the PATH,
289 // making sure that whatever executable that's found is not a same-named exe
290 // from clang itself to prevent clang from falling back to itself.
291 static std::string FindVisualStudioExecutable(const ToolChain &TC,
293 const auto &MSVC = static_cast<const toolchains::MSVCToolChain &>(TC);
294 SmallString<128> FilePath(MSVC.getSubDirectoryPath(
295 toolchains::MSVCToolChain::SubDirectoryType::Bin));
296 llvm::sys::path::append(FilePath, Exe);
297 return llvm::sys::fs::can_execute(FilePath) ? FilePath.str() : Exe;
300 void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA,
301 const InputInfo &Output,
302 const InputInfoList &Inputs,
304 const char *LinkingOutput) const {
305 ArgStringList CmdArgs;
307 auto &TC = static_cast<const toolchains::MSVCToolChain &>(getToolChain());
309 assert((Output.isFilename() || Output.isNothing()) && "invalid output");
310 if (Output.isFilename())
312 Args.MakeArgString(std::string("-out:") + Output.getFilename()));
314 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles) &&
315 !C.getDriver().IsCLMode())
316 CmdArgs.push_back("-defaultlib:libcmt");
318 if (!llvm::sys::Process::GetEnv("LIB")) {
319 // If the VC environment hasn't been configured (perhaps because the user
320 // did not run vcvarsall), try to build a consistent link environment. If
321 // the environment variable is set however, assume the user knows what
323 CmdArgs.push_back(Args.MakeArgString(
325 TC.getSubDirectoryPath(
326 toolchains::MSVCToolChain::SubDirectoryType::Lib)));
328 if (TC.useUniversalCRT()) {
329 std::string UniversalCRTLibPath;
330 if (TC.getUniversalCRTLibraryPath(UniversalCRTLibPath))
332 Args.MakeArgString(Twine("-libpath:") + UniversalCRTLibPath));
335 std::string WindowsSdkLibPath;
336 if (TC.getWindowsSDKLibraryPath(WindowsSdkLibPath))
338 Args.MakeArgString(std::string("-libpath:") + WindowsSdkLibPath));
341 if (!C.getDriver().IsCLMode() && Args.hasArg(options::OPT_L))
342 for (const auto &LibPath : Args.getAllArgValues(options::OPT_L))
343 CmdArgs.push_back(Args.MakeArgString("-libpath:" + LibPath));
345 CmdArgs.push_back("-nologo");
347 if (Args.hasArg(options::OPT_g_Group, options::OPT__SLASH_Z7,
348 options::OPT__SLASH_Zd))
349 CmdArgs.push_back("-debug");
351 bool DLL = Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd,
352 options::OPT_shared);
354 CmdArgs.push_back(Args.MakeArgString("-dll"));
356 SmallString<128> ImplibName(Output.getFilename());
357 llvm::sys::path::replace_extension(ImplibName, "lib");
358 CmdArgs.push_back(Args.MakeArgString(std::string("-implib:") + ImplibName));
361 if (TC.getSanitizerArgs().needsAsanRt()) {
362 CmdArgs.push_back(Args.MakeArgString("-debug"));
363 CmdArgs.push_back(Args.MakeArgString("-incremental:no"));
364 if (TC.getSanitizerArgs().needsSharedAsanRt() ||
365 Args.hasArg(options::OPT__SLASH_MD, options::OPT__SLASH_MDd)) {
366 for (const auto &Lib : {"asan_dynamic", "asan_dynamic_runtime_thunk"})
367 CmdArgs.push_back(TC.getCompilerRTArgString(Args, Lib));
368 // Make sure the dynamic runtime thunk is not optimized out at link time
369 // to ensure proper SEH handling.
370 CmdArgs.push_back(Args.MakeArgString(
371 TC.getArch() == llvm::Triple::x86
372 ? "-include:___asan_seh_interceptor"
373 : "-include:__asan_seh_interceptor"));
374 // Make sure the linker consider all object files from the dynamic runtime
376 CmdArgs.push_back(Args.MakeArgString(std::string("-wholearchive:") +
377 TC.getCompilerRT(Args, "asan_dynamic_runtime_thunk")));
379 CmdArgs.push_back(TC.getCompilerRTArgString(Args, "asan_dll_thunk"));
381 for (const auto &Lib : {"asan", "asan_cxx"}) {
382 CmdArgs.push_back(TC.getCompilerRTArgString(Args, Lib));
383 // Make sure the linker consider all object files from the static lib.
384 // This is necessary because instrumented dlls need access to all the
385 // interface exported by the static lib in the main executable.
386 CmdArgs.push_back(Args.MakeArgString(std::string("-wholearchive:") +
387 TC.getCompilerRT(Args, Lib)));
392 Args.AddAllArgValues(CmdArgs, options::OPT__SLASH_link);
394 if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
395 options::OPT_fno_openmp, false)) {
396 CmdArgs.push_back("-nodefaultlib:vcomp.lib");
397 CmdArgs.push_back("-nodefaultlib:vcompd.lib");
398 CmdArgs.push_back(Args.MakeArgString(std::string("-libpath:") +
399 TC.getDriver().Dir + "/../lib"));
400 switch (TC.getDriver().getOpenMPRuntime(Args)) {
401 case Driver::OMPRT_OMP:
402 CmdArgs.push_back("-defaultlib:libomp.lib");
404 case Driver::OMPRT_IOMP5:
405 CmdArgs.push_back("-defaultlib:libiomp5md.lib");
407 case Driver::OMPRT_GOMP:
409 case Driver::OMPRT_Unknown:
410 // Already diagnosed.
415 // Add compiler-rt lib in case if it was explicitly
416 // specified as an argument for --rtlib option.
417 if (!Args.hasArg(options::OPT_nostdlib)) {
418 AddRunTimeLibs(TC, TC.getDriver(), CmdArgs, Args);
421 // Add filenames, libraries, and other linker inputs.
422 for (const auto &Input : Inputs) {
423 if (Input.isFilename()) {
424 CmdArgs.push_back(Input.getFilename());
428 const Arg &A = Input.getInputArg();
430 // Render -l options differently for the MSVC linker.
431 if (A.getOption().matches(options::OPT_l)) {
432 StringRef Lib = A.getValue();
433 const char *LinkLibArg;
434 if (Lib.endswith(".lib"))
435 LinkLibArg = Args.MakeArgString(Lib);
437 LinkLibArg = Args.MakeArgString(Lib + ".lib");
438 CmdArgs.push_back(LinkLibArg);
442 // Otherwise, this is some other kind of linker input option like -Wl, -z,
443 // or -L. Render it, even if MSVC doesn't understand it.
444 A.renderAsInput(Args, CmdArgs);
447 TC.addProfileRTLibs(Args, CmdArgs);
449 std::vector<const char *> Environment;
451 // We need to special case some linker paths. In the case of lld, we need to
452 // translate 'lld' into 'lld-link', and in the case of the regular msvc
453 // linker, we need to use a special search algorithm.
454 llvm::SmallString<128> linkPath;
455 StringRef Linker = Args.getLastArgValue(options::OPT_fuse_ld_EQ, "link");
456 if (Linker.equals_lower("lld"))
459 if (Linker.equals_lower("link")) {
460 // If we're using the MSVC linker, it's not sufficient to just use link
461 // from the program PATH, because other environments like GnuWin32 install
462 // their own link.exe which may come first.
463 linkPath = FindVisualStudioExecutable(TC, "link.exe");
466 // When cross-compiling with VS2017 or newer, link.exe expects to have
467 // its containing bin directory at the top of PATH, followed by the
468 // native target bin directory.
469 // e.g. when compiling for x86 on an x64 host, PATH should start with:
470 // /bin/HostX64/x86;/bin/HostX64/x64
471 if (TC.getIsVS2017OrNewer() &&
472 llvm::Triple(llvm::sys::getProcessTriple()).getArch() != TC.getArch()) {
473 auto HostArch = llvm::Triple(llvm::sys::getProcessTriple()).getArch();
476 std::unique_ptr<wchar_t[], decltype(&FreeEnvironmentStringsW)>(
477 GetEnvironmentStringsW(), FreeEnvironmentStringsW);
479 goto SkipSettingEnvironment;
482 size_t EnvBlockLen = 0;
483 while (EnvBlockWide[EnvBlockLen] != L'\0') {
485 EnvBlockLen += std::wcslen(&EnvBlockWide[EnvBlockLen]) +
486 1 /*string null-terminator*/;
488 ++EnvBlockLen; // add the block null-terminator
490 std::string EnvBlock;
491 if (!llvm::convertUTF16ToUTF8String(
492 llvm::ArrayRef<char>(reinterpret_cast<char *>(EnvBlockWide.get()),
493 EnvBlockLen * sizeof(EnvBlockWide[0])),
495 goto SkipSettingEnvironment;
497 Environment.reserve(EnvCount);
499 // Now loop over each string in the block and copy them into the
500 // environment vector, adjusting the PATH variable as needed when we
502 for (const char *Cursor = EnvBlock.data(); *Cursor != '\0';) {
503 llvm::StringRef EnvVar(Cursor);
504 if (EnvVar.startswith_lower("path=")) {
505 using SubDirectoryType = toolchains::MSVCToolChain::SubDirectoryType;
506 constexpr size_t PrefixLen = 5; // strlen("path=")
507 Environment.push_back(Args.MakeArgString(
508 EnvVar.substr(0, PrefixLen) +
509 TC.getSubDirectoryPath(SubDirectoryType::Bin) +
510 llvm::Twine(llvm::sys::EnvPathSeparator) +
511 TC.getSubDirectoryPath(SubDirectoryType::Bin, HostArch) +
512 (EnvVar.size() > PrefixLen
513 ? llvm::Twine(llvm::sys::EnvPathSeparator) +
514 EnvVar.substr(PrefixLen)
517 Environment.push_back(Args.MakeArgString(EnvVar));
519 Cursor += EnvVar.size() + 1 /*null-terminator*/;
522 SkipSettingEnvironment:;
526 llvm::sys::path::replace_extension(linkPath, "exe");
527 linkPath = TC.GetProgramPath(linkPath.c_str());
530 auto LinkCmd = llvm::make_unique<Command>(
531 JA, *this, Args.MakeArgString(linkPath), CmdArgs, Inputs);
532 if (!Environment.empty())
533 LinkCmd->setEnvironment(Environment);
534 C.addCommand(std::move(LinkCmd));
537 void visualstudio::Compiler::ConstructJob(Compilation &C, const JobAction &JA,
538 const InputInfo &Output,
539 const InputInfoList &Inputs,
541 const char *LinkingOutput) const {
542 C.addCommand(GetCommand(C, JA, Output, Inputs, Args, LinkingOutput));
545 std::unique_ptr<Command> visualstudio::Compiler::GetCommand(
546 Compilation &C, const JobAction &JA, const InputInfo &Output,
547 const InputInfoList &Inputs, const ArgList &Args,
548 const char *LinkingOutput) const {
549 ArgStringList CmdArgs;
550 CmdArgs.push_back("/nologo");
551 CmdArgs.push_back("/c"); // Compile only.
552 CmdArgs.push_back("/W0"); // No warnings.
554 // The goal is to be able to invoke this tool correctly based on
555 // any flag accepted by clang-cl.
557 // These are spelled the same way in clang and cl.exe,.
558 Args.AddAllArgs(CmdArgs, {options::OPT_D, options::OPT_U, options::OPT_I});
560 // Optimization level.
561 if (Arg *A = Args.getLastArg(options::OPT_fbuiltin, options::OPT_fno_builtin))
562 CmdArgs.push_back(A->getOption().getID() == options::OPT_fbuiltin ? "/Oi"
564 if (Arg *A = Args.getLastArg(options::OPT_O, options::OPT_O0)) {
565 if (A->getOption().getID() == options::OPT_O0) {
566 CmdArgs.push_back("/Od");
568 CmdArgs.push_back("/Og");
570 StringRef OptLevel = A->getValue();
571 if (OptLevel == "s" || OptLevel == "z")
572 CmdArgs.push_back("/Os");
574 CmdArgs.push_back("/Ot");
576 CmdArgs.push_back("/Ob2");
579 if (Arg *A = Args.getLastArg(options::OPT_fomit_frame_pointer,
580 options::OPT_fno_omit_frame_pointer))
581 CmdArgs.push_back(A->getOption().getID() == options::OPT_fomit_frame_pointer
584 if (!Args.hasArg(options::OPT_fwritable_strings))
585 CmdArgs.push_back("/GF");
587 // Flags for which clang-cl has an alias.
588 // FIXME: How can we ensure this stays in sync with relevant clang-cl options?
590 if (Args.hasFlag(options::OPT__SLASH_GR_, options::OPT__SLASH_GR,
592 CmdArgs.push_back("/GR-");
594 if (Args.hasFlag(options::OPT__SLASH_GS_, options::OPT__SLASH_GS,
596 CmdArgs.push_back("/GS-");
598 if (Arg *A = Args.getLastArg(options::OPT_ffunction_sections,
599 options::OPT_fno_function_sections))
600 CmdArgs.push_back(A->getOption().getID() == options::OPT_ffunction_sections
603 if (Arg *A = Args.getLastArg(options::OPT_fdata_sections,
604 options::OPT_fno_data_sections))
606 A->getOption().getID() == options::OPT_fdata_sections ? "/Gw" : "/Gw-");
607 if (Args.hasArg(options::OPT_fsyntax_only))
608 CmdArgs.push_back("/Zs");
609 if (Args.hasArg(options::OPT_g_Flag, options::OPT_gline_tables_only,
610 options::OPT__SLASH_Z7))
611 CmdArgs.push_back("/Z7");
613 std::vector<std::string> Includes =
614 Args.getAllArgValues(options::OPT_include);
615 for (const auto &Include : Includes)
616 CmdArgs.push_back(Args.MakeArgString(std::string("/FI") + Include));
618 // Flags that can simply be passed through.
619 Args.AddAllArgs(CmdArgs, options::OPT__SLASH_LD);
620 Args.AddAllArgs(CmdArgs, options::OPT__SLASH_LDd);
621 Args.AddAllArgs(CmdArgs, options::OPT__SLASH_GX);
622 Args.AddAllArgs(CmdArgs, options::OPT__SLASH_GX_);
623 Args.AddAllArgs(CmdArgs, options::OPT__SLASH_EH);
624 Args.AddAllArgs(CmdArgs, options::OPT__SLASH_Zl);
626 // The order of these flags is relevant, so pick the last one.
627 if (Arg *A = Args.getLastArg(options::OPT__SLASH_MD, options::OPT__SLASH_MDd,
628 options::OPT__SLASH_MT, options::OPT__SLASH_MTd))
629 A->render(Args, CmdArgs);
631 // Use MSVC's default threadsafe statics behaviour unless there was a flag.
632 if (Arg *A = Args.getLastArg(options::OPT_fthreadsafe_statics,
633 options::OPT_fno_threadsafe_statics)) {
634 CmdArgs.push_back(A->getOption().getID() == options::OPT_fthreadsafe_statics
635 ? "/Zc:threadSafeInit"
636 : "/Zc:threadSafeInit-");
639 // Pass through all unknown arguments so that the fallback command can see
641 Args.AddAllArgs(CmdArgs, options::OPT_UNKNOWN);
644 assert(Inputs.size() == 1);
645 const InputInfo &II = Inputs[0];
646 assert(II.getType() == types::TY_C || II.getType() == types::TY_CXX);
647 CmdArgs.push_back(II.getType() == types::TY_C ? "/Tc" : "/Tp");
649 CmdArgs.push_back(II.getFilename());
651 II.getInputArg().renderAsInput(Args, CmdArgs);
654 assert(Output.getType() == types::TY_Object);
656 Args.MakeArgString(std::string("/Fo") + Output.getFilename());
657 CmdArgs.push_back(Fo);
659 std::string Exec = FindVisualStudioExecutable(getToolChain(), "cl.exe");
660 return llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Exec),
664 MSVCToolChain::MSVCToolChain(const Driver &D, const llvm::Triple &Triple,
666 : ToolChain(D, Triple, Args), CudaInstallation(D, Triple, Args) {
667 getProgramPaths().push_back(getDriver().getInstalledDir());
668 if (getDriver().getInstalledDir() != getDriver().Dir)
669 getProgramPaths().push_back(getDriver().Dir);
671 // Check the environment first, since that's probably the user telling us
672 // what they want to use.
673 // Failing that, just try to find the newest Visual Studio version we can
674 // and use its default VC toolchain.
675 findVCToolChainViaEnvironment(VCToolChainPath, IsVS2017OrNewer) ||
676 findVCToolChainViaSetupConfig(VCToolChainPath, IsVS2017OrNewer) ||
677 findVCToolChainViaRegistry(VCToolChainPath, IsVS2017OrNewer);
680 Tool *MSVCToolChain::buildLinker() const {
681 if (VCToolChainPath.empty())
682 getDriver().Diag(clang::diag::warn_drv_msvc_not_found);
683 return new tools::visualstudio::Linker(*this);
686 Tool *MSVCToolChain::buildAssembler() const {
687 if (getTriple().isOSBinFormatMachO())
688 return new tools::darwin::Assembler(*this);
689 getDriver().Diag(clang::diag::err_no_external_assembler);
693 bool MSVCToolChain::IsIntegratedAssemblerDefault() const {
697 bool MSVCToolChain::IsUnwindTablesDefault() const {
698 // Emit unwind tables by default on Win64. All non-x86_32 Windows platforms
699 // such as ARM and PPC actually require unwind tables, but LLVM doesn't know
700 // how to generate them yet.
702 // Don't emit unwind tables by default for MachO targets.
703 if (getTriple().isOSBinFormatMachO())
706 return getArch() == llvm::Triple::x86_64;
709 bool MSVCToolChain::isPICDefault() const {
710 return getArch() == llvm::Triple::x86_64;
713 bool MSVCToolChain::isPIEDefault() const {
717 bool MSVCToolChain::isPICDefaultForced() const {
718 return getArch() == llvm::Triple::x86_64;
721 void MSVCToolChain::AddCudaIncludeArgs(const ArgList &DriverArgs,
722 ArgStringList &CC1Args) const {
723 CudaInstallation.AddCudaIncludeArgs(DriverArgs, CC1Args);
726 void MSVCToolChain::printVerboseInfo(raw_ostream &OS) const {
727 CudaInstallation.print(OS);
730 // Windows SDKs and VC Toolchains group their contents into subdirectories based
731 // on the target architecture. This function converts an llvm::Triple::ArchType
732 // to the corresponding subdirectory name.
733 static const char *llvmArchToWindowsSDKArch(llvm::Triple::ArchType Arch) {
734 using ArchType = llvm::Triple::ArchType;
738 case ArchType::x86_64:
747 // Similar to the above function, but for Visual Studios before VS2017.
748 static const char *llvmArchToLegacyVCArch(llvm::Triple::ArchType Arch) {
749 using ArchType = llvm::Triple::ArchType;
752 // x86 is default in legacy VC toolchains.
753 // e.g. x86 libs are directly in /lib as opposed to /lib/x86.
755 case ArchType::x86_64:
764 // Get the path to a specific subdirectory in the current toolchain for
765 // a given target architecture.
766 // VS2017 changed the VC toolchain layout, so this should be used instead
767 // of hardcoding paths.
769 MSVCToolChain::getSubDirectoryPath(SubDirectoryType Type,
770 llvm::Triple::ArchType TargetArch) const {
771 llvm::SmallString<256> Path(VCToolChainPath);
773 case SubDirectoryType::Bin:
774 if (IsVS2017OrNewer) {
776 llvm::Triple(llvm::sys::getProcessTriple()).isArch64Bit();
777 llvm::sys::path::append(Path, "bin", (HostIsX64 ? "HostX64" : "HostX86"),
778 llvmArchToWindowsSDKArch(TargetArch));
781 llvm::sys::path::append(Path, "bin", llvmArchToLegacyVCArch(TargetArch));
784 case SubDirectoryType::Include:
785 llvm::sys::path::append(Path, "include");
787 case SubDirectoryType::Lib:
788 llvm::sys::path::append(
789 Path, "lib", IsVS2017OrNewer ? llvmArchToWindowsSDKArch(TargetArch)
790 : llvmArchToLegacyVCArch(TargetArch));
797 static bool readFullStringValue(HKEY hkey, const char *valueName,
798 std::string &value) {
799 std::wstring WideValueName;
800 if (!llvm::ConvertUTF8toWide(valueName, WideValueName))
806 // First just query for the required size.
807 result = RegQueryValueExW(hkey, WideValueName.c_str(), NULL, &type, NULL,
809 if (result != ERROR_SUCCESS || type != REG_SZ || !valueSize)
811 std::vector<BYTE> buffer(valueSize);
812 result = RegQueryValueExW(hkey, WideValueName.c_str(), NULL, NULL, &buffer[0],
814 if (result == ERROR_SUCCESS) {
815 std::wstring WideValue(reinterpret_cast<const wchar_t *>(buffer.data()),
816 valueSize / sizeof(wchar_t));
817 if (valueSize && WideValue.back() == L'\0') {
818 WideValue.pop_back();
820 // The destination buffer must be empty as an invariant of the conversion
821 // function; but this function is sometimes called in a loop that passes in
822 // the same buffer, however. Simply clear it out so we can overwrite it.
824 return llvm::convertWideToUTF8(WideValue, value);
830 /// \brief Read registry string.
831 /// This also supports a means to look for high-versioned keys by use
832 /// of a $VERSION placeholder in the key path.
833 /// $VERSION in the key path is a placeholder for the version number,
834 /// causing the highest value path to be searched for and used.
835 /// I.e. "SOFTWARE\\Microsoft\\VisualStudio\\$VERSION".
836 /// There can be additional characters in the component. Only the numeric
837 /// characters are compared. This function only searches HKLM.
838 static bool getSystemRegistryString(const char *keyPath, const char *valueName,
839 std::string &value, std::string *phValue) {
843 HKEY hRootKey = HKEY_LOCAL_MACHINE;
846 bool returnValue = false;
848 const char *placeHolder = strstr(keyPath, "$VERSION");
849 std::string bestName;
850 // If we have a $VERSION placeholder, do the highest-version search.
852 const char *keyEnd = placeHolder - 1;
853 const char *nextKey = placeHolder;
854 // Find end of previous key.
855 while ((keyEnd > keyPath) && (*keyEnd != '\\'))
857 // Find end of key containing $VERSION.
858 while (*nextKey && (*nextKey != '\\'))
860 size_t partialKeyLength = keyEnd - keyPath;
861 char partialKey[256];
862 if (partialKeyLength >= sizeof(partialKey))
863 partialKeyLength = sizeof(partialKey) - 1;
864 strncpy(partialKey, keyPath, partialKeyLength);
865 partialKey[partialKeyLength] = '\0';
867 lResult = RegOpenKeyExA(hRootKey, partialKey, 0, KEY_READ | KEY_WOW64_32KEY,
869 if (lResult == ERROR_SUCCESS) {
871 double bestValue = 0.0;
872 DWORD index, size = sizeof(keyName) - 1;
873 for (index = 0; RegEnumKeyExA(hTopKey, index, keyName, &size, NULL, NULL,
874 NULL, NULL) == ERROR_SUCCESS;
876 const char *sp = keyName;
877 while (*sp && !isDigit(*sp))
881 const char *ep = sp + 1;
882 while (*ep && (isDigit(*ep) || (*ep == '.')))
885 strncpy(numBuf, sp, sizeof(numBuf) - 1);
886 numBuf[sizeof(numBuf) - 1] = '\0';
887 double dvalue = strtod(numBuf, NULL);
888 if (dvalue > bestValue) {
889 // Test that InstallDir is indeed there before keeping this index.
890 // Open the chosen key path remainder.
892 // Append rest of key.
893 bestName.append(nextKey);
894 lResult = RegOpenKeyExA(hTopKey, bestName.c_str(), 0,
895 KEY_READ | KEY_WOW64_32KEY, &hKey);
896 if (lResult == ERROR_SUCCESS) {
897 if (readFullStringValue(hKey, valueName, value)) {
906 size = sizeof(keyName) - 1;
908 RegCloseKey(hTopKey);
912 RegOpenKeyExA(hRootKey, keyPath, 0, KEY_READ | KEY_WOW64_32KEY, &hKey);
913 if (lResult == ERROR_SUCCESS) {
914 if (readFullStringValue(hKey, valueName, value))
925 // Find the most recent version of Universal CRT or Windows 10 SDK.
926 // vcvarsqueryregistry.bat from Visual Studio 2015 sorts entries in the include
927 // directory by name and uses the last one of the list.
928 // So we compare entry names lexicographically to find the greatest one.
929 static bool getWindows10SDKVersionFromPath(const std::string &SDKPath,
930 std::string &SDKVersion) {
934 llvm::SmallString<128> IncludePath(SDKPath);
935 llvm::sys::path::append(IncludePath, "Include");
936 for (llvm::sys::fs::directory_iterator DirIt(IncludePath, EC), DirEnd;
937 DirIt != DirEnd && !EC; DirIt.increment(EC)) {
938 if (!llvm::sys::fs::is_directory(DirIt->path()))
940 StringRef CandidateName = llvm::sys::path::filename(DirIt->path());
941 // If WDK is installed, there could be subfolders like "wdf" in the
942 // "Include" directory.
943 // Allow only directories which names start with "10.".
944 if (!CandidateName.startswith("10."))
946 if (CandidateName > SDKVersion)
947 SDKVersion = CandidateName;
950 return !SDKVersion.empty();
953 /// \brief Get Windows SDK installation directory.
954 static bool getWindowsSDKDir(std::string &Path, int &Major,
955 std::string &WindowsSDKIncludeVersion,
956 std::string &WindowsSDKLibVersion) {
957 std::string RegistrySDKVersion;
958 // Try the Windows registry.
959 if (!getSystemRegistryString(
960 "SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\$VERSION",
961 "InstallationFolder", Path, &RegistrySDKVersion))
963 if (Path.empty() || RegistrySDKVersion.empty())
966 WindowsSDKIncludeVersion.clear();
967 WindowsSDKLibVersion.clear();
969 std::sscanf(RegistrySDKVersion.c_str(), "v%d.", &Major);
973 // Windows SDK 8.x installs libraries in a folder whose names depend on the
974 // version of the OS you're targeting. By default choose the newest, which
975 // usually corresponds to the version of the OS you've installed the SDK on.
976 const char *Tests[] = {"winv6.3", "win8", "win7"};
977 for (const char *Test : Tests) {
978 llvm::SmallString<128> TestPath(Path);
979 llvm::sys::path::append(TestPath, "Lib", Test);
980 if (llvm::sys::fs::exists(TestPath.c_str())) {
981 WindowsSDKLibVersion = Test;
985 return !WindowsSDKLibVersion.empty();
988 if (!getWindows10SDKVersionFromPath(Path, WindowsSDKIncludeVersion))
990 WindowsSDKLibVersion = WindowsSDKIncludeVersion;
993 // Unsupported SDK version
997 // Gets the library path required to link against the Windows SDK.
998 bool MSVCToolChain::getWindowsSDKLibraryPath(std::string &path) const {
1001 std::string windowsSDKIncludeVersion;
1002 std::string windowsSDKLibVersion;
1005 if (!getWindowsSDKDir(sdkPath, sdkMajor, windowsSDKIncludeVersion,
1006 windowsSDKLibVersion))
1009 llvm::SmallString<128> libPath(sdkPath);
1010 llvm::sys::path::append(libPath, "Lib");
1011 if (sdkMajor >= 8) {
1012 llvm::sys::path::append(libPath, windowsSDKLibVersion, "um",
1013 llvmArchToWindowsSDKArch(getArch()));
1015 switch (getArch()) {
1016 // In Windows SDK 7.x, x86 libraries are directly in the Lib folder.
1017 case llvm::Triple::x86:
1019 case llvm::Triple::x86_64:
1020 llvm::sys::path::append(libPath, "x64");
1022 case llvm::Triple::arm:
1023 // It is not necessary to link against Windows SDK 7.x when targeting ARM.
1030 path = libPath.str();
1034 // Check if the Include path of a specified version of Visual Studio contains
1035 // specific header files. If not, they are probably shipped with Universal CRT.
1036 bool MSVCToolChain::useUniversalCRT() const {
1037 llvm::SmallString<128> TestPath(
1038 getSubDirectoryPath(SubDirectoryType::Include));
1039 llvm::sys::path::append(TestPath, "stdlib.h");
1040 return !llvm::sys::fs::exists(TestPath);
1043 static bool getUniversalCRTSdkDir(std::string &Path, std::string &UCRTVersion) {
1044 // vcvarsqueryregistry.bat for Visual Studio 2015 queries the registry
1045 // for the specific key "KitsRoot10". So do we.
1046 if (!getSystemRegistryString(
1047 "SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots", "KitsRoot10",
1051 return getWindows10SDKVersionFromPath(Path, UCRTVersion);
1054 bool MSVCToolChain::getUniversalCRTLibraryPath(std::string &Path) const {
1055 std::string UniversalCRTSdkPath;
1056 std::string UCRTVersion;
1059 if (!getUniversalCRTSdkDir(UniversalCRTSdkPath, UCRTVersion))
1062 StringRef ArchName = llvmArchToWindowsSDKArch(getArch());
1063 if (ArchName.empty())
1066 llvm::SmallString<128> LibPath(UniversalCRTSdkPath);
1067 llvm::sys::path::append(LibPath, "Lib", UCRTVersion, "ucrt", ArchName);
1069 Path = LibPath.str();
1073 static VersionTuple getMSVCVersionFromTriple(const llvm::Triple &Triple) {
1074 unsigned Major, Minor, Micro;
1075 Triple.getEnvironmentVersion(Major, Minor, Micro);
1076 if (Major || Minor || Micro)
1077 return VersionTuple(Major, Minor, Micro);
1078 return VersionTuple();
1081 static VersionTuple getMSVCVersionFromExe(const std::string &BinDir) {
1082 VersionTuple Version;
1084 SmallString<128> ClExe(BinDir);
1085 llvm::sys::path::append(ClExe, "cl.exe");
1087 std::wstring ClExeWide;
1088 if (!llvm::ConvertUTF8toWide(ClExe.c_str(), ClExeWide))
1091 const DWORD VersionSize = ::GetFileVersionInfoSizeW(ClExeWide.c_str(),
1093 if (VersionSize == 0)
1096 SmallVector<uint8_t, 4 * 1024> VersionBlock(VersionSize);
1097 if (!::GetFileVersionInfoW(ClExeWide.c_str(), 0, VersionSize,
1098 VersionBlock.data()))
1101 VS_FIXEDFILEINFO *FileInfo = nullptr;
1102 UINT FileInfoSize = 0;
1103 if (!::VerQueryValueW(VersionBlock.data(), L"\\",
1104 reinterpret_cast<LPVOID *>(&FileInfo), &FileInfoSize) ||
1105 FileInfoSize < sizeof(*FileInfo))
1108 const unsigned Major = (FileInfo->dwFileVersionMS >> 16) & 0xFFFF;
1109 const unsigned Minor = (FileInfo->dwFileVersionMS ) & 0xFFFF;
1110 const unsigned Micro = (FileInfo->dwFileVersionLS >> 16) & 0xFFFF;
1112 Version = VersionTuple(Major, Minor, Micro);
1117 void MSVCToolChain::AddSystemIncludeWithSubfolder(
1118 const ArgList &DriverArgs, ArgStringList &CC1Args,
1119 const std::string &folder, const Twine &subfolder1, const Twine &subfolder2,
1120 const Twine &subfolder3) const {
1121 llvm::SmallString<128> path(folder);
1122 llvm::sys::path::append(path, subfolder1, subfolder2, subfolder3);
1123 addSystemInclude(DriverArgs, CC1Args, path);
1126 void MSVCToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
1127 ArgStringList &CC1Args) const {
1128 if (DriverArgs.hasArg(options::OPT_nostdinc))
1131 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
1132 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, getDriver().ResourceDir,
1136 // Add %INCLUDE%-like directories from the -imsvc flag.
1137 for (const auto &Path : DriverArgs.getAllArgValues(options::OPT__SLASH_imsvc))
1138 addSystemInclude(DriverArgs, CC1Args, Path);
1140 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
1143 // Honor %INCLUDE%. It should know essential search paths with vcvarsall.bat.
1144 if (llvm::Optional<std::string> cl_include_dir =
1145 llvm::sys::Process::GetEnv("INCLUDE")) {
1146 SmallVector<StringRef, 8> Dirs;
1147 StringRef(*cl_include_dir)
1148 .split(Dirs, ";", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
1149 for (StringRef Dir : Dirs)
1150 addSystemInclude(DriverArgs, CC1Args, Dir);
1155 // When built with access to the proper Windows APIs, try to actually find
1156 // the correct include paths first.
1157 if (!VCToolChainPath.empty()) {
1158 addSystemInclude(DriverArgs, CC1Args,
1159 getSubDirectoryPath(SubDirectoryType::Include));
1161 if (useUniversalCRT()) {
1162 std::string UniversalCRTSdkPath;
1163 std::string UCRTVersion;
1164 if (getUniversalCRTSdkDir(UniversalCRTSdkPath, UCRTVersion)) {
1165 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, UniversalCRTSdkPath,
1166 "Include", UCRTVersion, "ucrt");
1170 std::string WindowsSDKDir;
1172 std::string windowsSDKIncludeVersion;
1173 std::string windowsSDKLibVersion;
1174 if (getWindowsSDKDir(WindowsSDKDir, major, windowsSDKIncludeVersion,
1175 windowsSDKLibVersion)) {
1177 // Note: windowsSDKIncludeVersion is empty for SDKs prior to v10.
1178 // Anyway, llvm::sys::path::append is able to manage it.
1179 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
1180 "include", windowsSDKIncludeVersion,
1182 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
1183 "include", windowsSDKIncludeVersion,
1185 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
1186 "include", windowsSDKIncludeVersion,
1189 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
1197 #if defined(LLVM_ON_WIN32)
1198 // As a fallback, select default install paths.
1199 // FIXME: Don't guess drives and paths like this on Windows.
1200 const StringRef Paths[] = {
1201 "C:/Program Files/Microsoft Visual Studio 10.0/VC/include",
1202 "C:/Program Files/Microsoft Visual Studio 9.0/VC/include",
1203 "C:/Program Files/Microsoft Visual Studio 9.0/VC/PlatformSDK/Include",
1204 "C:/Program Files/Microsoft Visual Studio 8/VC/include",
1205 "C:/Program Files/Microsoft Visual Studio 8/VC/PlatformSDK/Include"
1207 addSystemIncludes(DriverArgs, CC1Args, Paths);
1211 void MSVCToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
1212 ArgStringList &CC1Args) const {
1213 // FIXME: There should probably be logic here to find libc++ on Windows.
1216 VersionTuple MSVCToolChain::computeMSVCVersion(const Driver *D,
1217 const ArgList &Args) const {
1218 bool IsWindowsMSVC = getTriple().isWindowsMSVCEnvironment();
1219 VersionTuple MSVT = ToolChain::computeMSVCVersion(D, Args);
1221 MSVT = getMSVCVersionFromTriple(getTriple());
1222 if (MSVT.empty() && IsWindowsMSVC)
1223 MSVT = getMSVCVersionFromExe(getSubDirectoryPath(SubDirectoryType::Bin));
1225 Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions,
1227 // -fms-compatibility-version=18.00 is default.
1228 // FIXME: Consider bumping this to 19 (MSVC2015) soon.
1229 MSVT = VersionTuple(18);
1235 MSVCToolChain::ComputeEffectiveClangTriple(const ArgList &Args,
1236 types::ID InputType) const {
1237 // The MSVC version doesn't care about the architecture, even though it
1238 // may look at the triple internally.
1239 VersionTuple MSVT = computeMSVCVersion(/*D=*/nullptr, Args);
1240 MSVT = VersionTuple(MSVT.getMajor(), MSVT.getMinor().getValueOr(0),
1241 MSVT.getSubminor().getValueOr(0));
1243 // For the rest of the triple, however, a computed architecture name may
1245 llvm::Triple Triple(ToolChain::ComputeEffectiveClangTriple(Args, InputType));
1246 if (Triple.getEnvironment() == llvm::Triple::MSVC) {
1247 StringRef ObjFmt = Triple.getEnvironmentName().split('-').second;
1249 Triple.setEnvironmentName((Twine("msvc") + MSVT.getAsString()).str());
1251 Triple.setEnvironmentName(
1252 (Twine("msvc") + MSVT.getAsString() + Twine('-') + ObjFmt).str());
1254 return Triple.getTriple();
1257 SanitizerMask MSVCToolChain::getSupportedSanitizers() const {
1258 SanitizerMask Res = ToolChain::getSupportedSanitizers();
1259 Res |= SanitizerKind::Address;
1263 static void TranslateOptArg(Arg *A, llvm::opt::DerivedArgList &DAL,
1264 bool SupportsForcingFramePointer,
1265 const char *ExpandChar, const OptTable &Opts) {
1266 assert(A->getOption().matches(options::OPT__SLASH_O));
1268 StringRef OptStr = A->getValue();
1269 for (size_t I = 0, E = OptStr.size(); I != E; ++I) {
1270 const char &OptChar = *(OptStr.data() + I);
1278 if (&OptChar == ExpandChar) {
1279 if (OptChar == 'd') {
1280 DAL.AddFlagArg(A, Opts.getOption(options::OPT_O0));
1282 if (OptChar == '1') {
1283 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "s");
1284 } else if (OptChar == '2' || OptChar == 'x') {
1285 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
1286 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "2");
1288 if (SupportsForcingFramePointer &&
1289 !DAL.hasArgNoClaim(options::OPT_fno_omit_frame_pointer))
1291 Opts.getOption(options::OPT_fomit_frame_pointer));
1292 if (OptChar == '1' || OptChar == '2')
1294 Opts.getOption(options::OPT_ffunction_sections));
1299 if (I + 1 != E && isdigit(OptStr[I + 1])) {
1300 switch (OptStr[I + 1]) {
1302 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_inline));
1305 DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_hint_functions));
1308 DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_functions));
1317 if (I + 1 != E && OptStr[I + 1] == '-') {
1319 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_builtin));
1321 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
1325 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "s");
1328 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "2");
1331 bool OmitFramePointer = true;
1332 if (I + 1 != E && OptStr[I + 1] == '-') {
1333 OmitFramePointer = false;
1336 if (SupportsForcingFramePointer) {
1337 if (OmitFramePointer)
1339 Opts.getOption(options::OPT_fomit_frame_pointer));
1342 A, Opts.getOption(options::OPT_fno_omit_frame_pointer));
1344 // Don't warn about /Oy- in 64-bit builds (where
1345 // SupportsForcingFramePointer is false). The flag having no effect
1346 // there is a compiler-internal optimization, and people shouldn't have
1347 // to special-case their build files for 64-bit clang-cl.
1356 static void TranslateDArg(Arg *A, llvm::opt::DerivedArgList &DAL,
1357 const OptTable &Opts) {
1358 assert(A->getOption().matches(options::OPT_D));
1360 StringRef Val = A->getValue();
1361 size_t Hash = Val.find('#');
1362 if (Hash == StringRef::npos || Hash > Val.find('=')) {
1367 std::string NewVal = Val;
1369 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_D), NewVal);
1372 llvm::opt::DerivedArgList *
1373 MSVCToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args,
1374 StringRef BoundArch, Action::OffloadKind) const {
1375 DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
1376 const OptTable &Opts = getDriver().getOpts();
1378 // /Oy and /Oy- only has an effect under X86-32.
1379 bool SupportsForcingFramePointer = getArch() == llvm::Triple::x86;
1381 // The -O[12xd] flag actually expands to several flags. We must desugar the
1382 // flags so that options embedded can be negated. For example, the '-O2' flag
1383 // enables '-Oy'. Expanding '-O2' into its constituent flags allows us to
1384 // correctly handle '-O2 -Oy-' where the trailing '-Oy-' disables a single
1387 // Note that this expansion logic only applies to the *last* of '[12xd]'.
1389 // First step is to search for the character we'd like to expand.
1390 const char *ExpandChar = nullptr;
1391 for (Arg *A : Args) {
1392 if (!A->getOption().matches(options::OPT__SLASH_O))
1394 StringRef OptStr = A->getValue();
1395 for (size_t I = 0, E = OptStr.size(); I != E; ++I) {
1396 char OptChar = OptStr[I];
1397 char PrevChar = I > 0 ? OptStr[I - 1] : '0';
1398 if (PrevChar == 'b') {
1399 // OptChar does not expand; it's an argument to the previous char.
1402 if (OptChar == '1' || OptChar == '2' || OptChar == 'x' || OptChar == 'd')
1403 ExpandChar = OptStr.data() + I;
1407 for (Arg *A : Args) {
1408 if (A->getOption().matches(options::OPT__SLASH_O)) {
1409 // The -O flag actually takes an amalgam of other options. For example,
1410 // '/Ogyb2' is equivalent to '/Og' '/Oy' '/Ob2'.
1411 TranslateOptArg(A, *DAL, SupportsForcingFramePointer, ExpandChar, Opts);
1412 } else if (A->getOption().matches(options::OPT_D)) {
1413 // Translate -Dfoo#bar into -Dfoo=bar.
1414 TranslateDArg(A, *DAL, Opts);