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