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