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