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