Clang Project

clang_source_code/lib/Driver/ToolChains/MSVC.cpp
1//===-- MSVC.cpp - MSVC ToolChain Implementations -------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "MSVC.h"
10#include "CommonArgs.h"
11#include "Darwin.h"
12#include "clang/Basic/CharInfo.h"
13#include "clang/Basic/Version.h"
14#include "clang/Driver/Compilation.h"
15#include "clang/Driver/Driver.h"
16#include "clang/Driver/DriverDiagnostic.h"
17#include "clang/Driver/Options.h"
18#include "clang/Driver/SanitizerArgs.h"
19#include "llvm/ADT/StringExtras.h"
20#include "llvm/ADT/StringSwitch.h"
21#include "llvm/Option/Arg.h"
22#include "llvm/Option/ArgList.h"
23#include "llvm/Support/ConvertUTF.h"
24#include "llvm/Support/ErrorHandling.h"
25#include "llvm/Support/FileSystem.h"
26#include "llvm/Support/Host.h"
27#include "llvm/Support/MemoryBuffer.h"
28#include "llvm/Support/Path.h"
29#include "llvm/Support/Process.h"
30#include <cstdio>
31
32#ifdef _WIN32
33  #define WIN32_LEAN_AND_MEAN
34  #define NOGDI
35  #ifndef NOMINMAX
36    #define NOMINMAX
37  #endif
38  #include <windows.h>
39#endif
40
41#ifdef _MSC_VER
42// Don't support SetupApi on MinGW.
43#define USE_MSVC_SETUP_API
44
45// Make sure this comes before MSVCSetupApi.h
46#include <comdef.h>
47
48#include "MSVCSetupApi.h"
49#include "llvm/Support/COM.h"
50_COM_SMARTPTR_TYPEDEF(ISetupConfiguration, __uuidof(ISetupConfiguration));
51_COM_SMARTPTR_TYPEDEF(ISetupConfiguration2, __uuidof(ISetupConfiguration2));
52_COM_SMARTPTR_TYPEDEF(ISetupHelper, __uuidof(ISetupHelper));
53_COM_SMARTPTR_TYPEDEF(IEnumSetupInstances, __uuidof(IEnumSetupInstances));
54_COM_SMARTPTR_TYPEDEF(ISetupInstance, __uuidof(ISetupInstance));
55_COM_SMARTPTR_TYPEDEF(ISetupInstance2, __uuidof(ISetupInstance2));
56#endif
57
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 *keyPathconst char *valueName,
67                                    std::string &valuestd::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::StringRef8PathEntries;
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"VSInstallPathnullptr) ||
278      getSystemRegistryString(R"(SOFTWARE\Microsoft\VCExpress\$VERSION)",
279                              "InstallDir"VSInstallPathnullptr)) {
280    if (!VSInstallPath.empty()) {
281      llvm::SmallString<256VCPath(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<128FilePath(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   (0) . __assert_fail ("(Output.isFilename() || Output.isNothing()) && \"invalid output\"", "/home/seafit/code_projects/clang_source/clang/lib/Driver/ToolChains/MSVC.cpp", 315, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">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      C.getDriver().Diag(clang::diag::warn_drv_msvc_not_found);
493
494#ifdef _WIN32
495    // When cross-compiling with VS2017 or newer, link.exe expects to have
496    // its containing bin directory at the top of PATH, followed by the
497    // native target bin directory.
498    // e.g. when compiling for x86 on an x64 host, PATH should start with:
499    // /bin/HostX64/x86;/bin/HostX64/x64
500    // This doesn't attempt to handle ToolsetLayout::DevDivInternal.
501    if (TC.getIsVS2017OrNewer() &&
502        llvm::Triple(llvm::sys::getProcessTriple()).getArch() != TC.getArch()) {
503      auto HostArch = llvm::Triple(llvm::sys::getProcessTriple()).getArch();
504
505      auto EnvBlockWide =
506          std::unique_ptr<wchar_t[], decltype(&FreeEnvironmentStringsW)>(
507              GetEnvironmentStringsW(), FreeEnvironmentStringsW);
508      if (!EnvBlockWide)
509        goto SkipSettingEnvironment;
510
511      size_t EnvCount = 0;
512      size_t EnvBlockLen = 0;
513      while (EnvBlockWide[EnvBlockLen] != L'\0') {
514        ++EnvCount;
515        EnvBlockLen += std::wcslen(&EnvBlockWide[EnvBlockLen]) +
516                       1 /*string null-terminator*/;
517      }
518      ++EnvBlockLen; // add the block null-terminator
519
520      std::string EnvBlock;
521      if (!llvm::convertUTF16ToUTF8String(
522              llvm::ArrayRef<char>(reinterpret_cast<char *>(EnvBlockWide.get()),
523                                   EnvBlockLen * sizeof(EnvBlockWide[0])),
524              EnvBlock))
525        goto SkipSettingEnvironment;
526
527      Environment.reserve(EnvCount);
528
529      // Now loop over each string in the block and copy them into the
530      // environment vector, adjusting the PATH variable as needed when we
531      // find it.
532      for (const char *Cursor = EnvBlock.data(); *Cursor != '\0';) {
533        llvm::StringRef EnvVar(Cursor);
534        if (EnvVar.startswith_lower("path=")) {
535          using SubDirectoryType = toolchains::MSVCToolChain::SubDirectoryType;
536          constexpr size_t PrefixLen = 5// strlen("path=")
537          Environment.push_back(Args.MakeArgString(
538              EnvVar.substr(0, PrefixLen) +
539              TC.getSubDirectoryPath(SubDirectoryType::Bin) +
540              llvm::Twine(llvm::sys::EnvPathSeparator) +
541              TC.getSubDirectoryPath(SubDirectoryType::Bin, HostArch) +
542              (EnvVar.size() > PrefixLen
543                   ? llvm::Twine(llvm::sys::EnvPathSeparator) +
544                         EnvVar.substr(PrefixLen)
545                   : "")));
546        } else {
547          Environment.push_back(Args.MakeArgString(EnvVar));
548        }
549        Cursor += EnvVar.size() + 1 /*null-terminator*/;
550      }
551    }
552  SkipSettingEnvironment:;
553#endif
554  } else {
555    linkPath = TC.GetProgramPath(Linker.str().c_str());
556  }
557
558  auto LinkCmd = llvm::make_unique<Command>(
559      JA, *this, Args.MakeArgString(linkPath), CmdArgs, Inputs);
560  if (!Environment.empty())
561    LinkCmd->setEnvironment(Environment);
562  C.addCommand(std::move(LinkCmd));
563}
564
565void visualstudio::Compiler::ConstructJob(Compilation &C, const JobAction &JA,
566                                          const InputInfo &Output,
567                                          const InputInfoList &Inputs,
568                                          const ArgList &Args,
569                                          const char *LinkingOutput) const {
570  C.addCommand(GetCommand(C, JA, Output, Inputs, Args, LinkingOutput));
571}
572
573std::unique_ptr<Command> visualstudio::Compiler::GetCommand(
574    Compilation &C, const JobAction &JA, const InputInfo &Output,
575    const InputInfoList &Inputs, const ArgList &Args,
576    const char *LinkingOutput) const {
577  ArgStringList CmdArgs;
578  CmdArgs.push_back("/nologo");
579  CmdArgs.push_back("/c");  // Compile only.
580  CmdArgs.push_back("/W0"); // No warnings.
581
582  // The goal is to be able to invoke this tool correctly based on
583  // any flag accepted by clang-cl.
584
585  // These are spelled the same way in clang and cl.exe,.
586  Args.AddAllArgs(CmdArgs, {options::OPT_D, options::OPT_U, options::OPT_I});
587
588  // Optimization level.
589  if (Arg *A = Args.getLastArg(options::OPT_fbuiltin, options::OPT_fno_builtin))
590    CmdArgs.push_back(A->getOption().getID() == options::OPT_fbuiltin ? "/Oi"
591                                                                      : "/Oi-");
592  if (Arg *A = Args.getLastArg(options::OPT_O, options::OPT_O0)) {
593    if (A->getOption().getID() == options::OPT_O0) {
594      CmdArgs.push_back("/Od");
595    } else {
596      CmdArgs.push_back("/Og");
597
598      StringRef OptLevel = A->getValue();
599      if (OptLevel == "s" || OptLevel == "z")
600        CmdArgs.push_back("/Os");
601      else
602        CmdArgs.push_back("/Ot");
603
604      CmdArgs.push_back("/Ob2");
605    }
606  }
607  if (Arg *A = Args.getLastArg(options::OPT_fomit_frame_pointer,
608                               options::OPT_fno_omit_frame_pointer))
609    CmdArgs.push_back(A->getOption().getID() == options::OPT_fomit_frame_pointer
610                          ? "/Oy"
611                          : "/Oy-");
612  if (!Args.hasArg(options::OPT_fwritable_strings))
613    CmdArgs.push_back("/GF");
614
615  // Flags for which clang-cl has an alias.
616  // FIXME: How can we ensure this stays in sync with relevant clang-cl options?
617
618  if (Args.hasFlag(options::OPT__SLASH_GR_, options::OPT__SLASH_GR,
619                   /*default=*/false))
620    CmdArgs.push_back("/GR-");
621
622  if (Args.hasFlag(options::OPT__SLASH_GS_, options::OPT__SLASH_GS,
623                   /*default=*/false))
624    CmdArgs.push_back("/GS-");
625
626  if (Arg *A = Args.getLastArg(options::OPT_ffunction_sections,
627                               options::OPT_fno_function_sections))
628    CmdArgs.push_back(A->getOption().getID() == options::OPT_ffunction_sections
629                          ? "/Gy"
630                          : "/Gy-");
631  if (Arg *A = Args.getLastArg(options::OPT_fdata_sections,
632                               options::OPT_fno_data_sections))
633    CmdArgs.push_back(
634        A->getOption().getID() == options::OPT_fdata_sections ? "/Gw" : "/Gw-");
635  if (Args.hasArg(options::OPT_fsyntax_only))
636    CmdArgs.push_back("/Zs");
637  if (Args.hasArg(options::OPT_g_Flag, options::OPT_gline_tables_only,
638                  options::OPT__SLASH_Z7))
639    CmdArgs.push_back("/Z7");
640
641  std::vector<std::string> Includes =
642      Args.getAllArgValues(options::OPT_include);
643  for (const auto &Include : Includes)
644    CmdArgs.push_back(Args.MakeArgString(std::string("/FI") + Include));
645
646  // Flags that can simply be passed through.
647  Args.AddAllArgs(CmdArgs, options::OPT__SLASH_LD);
648  Args.AddAllArgs(CmdArgs, options::OPT__SLASH_LDd);
649  Args.AddAllArgs(CmdArgs, options::OPT__SLASH_GX);
650  Args.AddAllArgs(CmdArgs, options::OPT__SLASH_GX_);
651  Args.AddAllArgs(CmdArgs, options::OPT__SLASH_EH);
652  Args.AddAllArgs(CmdArgs, options::OPT__SLASH_Zl);
653
654  // The order of these flags is relevant, so pick the last one.
655  if (Arg *A = Args.getLastArg(options::OPT__SLASH_MD, options::OPT__SLASH_MDd,
656                               options::OPT__SLASH_MT, options::OPT__SLASH_MTd))
657    A->render(Args, CmdArgs);
658
659  // Use MSVC's default threadsafe statics behaviour unless there was a flag.
660  if (Arg *A = Args.getLastArg(options::OPT_fthreadsafe_statics,
661                               options::OPT_fno_threadsafe_statics)) {
662    CmdArgs.push_back(A->getOption().getID() == options::OPT_fthreadsafe_statics
663                          ? "/Zc:threadSafeInit"
664                          : "/Zc:threadSafeInit-");
665  }
666
667  // Pass through all unknown arguments so that the fallback command can see
668  // them too.
669  Args.AddAllArgs(CmdArgs, options::OPT_UNKNOWN);
670
671  // Input filename.
672  assert(Inputs.size() == 1);
673  const InputInfo &II = Inputs[0];
674  assert(II.getType() == types::TY_C || II.getType() == types::TY_CXX);
675  CmdArgs.push_back(II.getType() == types::TY_C ? "/Tc" : "/Tp");
676  if (II.isFilename())
677    CmdArgs.push_back(II.getFilename());
678  else
679    II.getInputArg().renderAsInput(Args, CmdArgs);
680
681  // Output filename.
682  assert(Output.getType() == types::TY_Object);
683  const char *Fo =
684      Args.MakeArgString(std::string("/Fo") + Output.getFilename());
685  CmdArgs.push_back(Fo);
686
687  std::string Exec = FindVisualStudioExecutable(getToolChain(), "cl.exe");
688  return llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Exec),
689                                    CmdArgs, Inputs);
690}
691
692MSVCToolChain::MSVCToolChain(const Driver &D, const llvm::Triple &Triple,
693                             const ArgList &Args)
694    : ToolChain(D, Triple, Args), CudaInstallation(D, Triple, Args) {
695  getProgramPaths().push_back(getDriver().getInstalledDir());
696  if (getDriver().getInstalledDir() != getDriver().Dir)
697    getProgramPaths().push_back(getDriver().Dir);
698
699  // Check the environment first, since that's probably the user telling us
700  // what they want to use.
701  // Failing that, just try to find the newest Visual Studio version we can
702  // and use its default VC toolchain.
703  findVCToolChainViaEnvironment(VCToolChainPath, VSLayout) ||
704      findVCToolChainViaSetupConfig(VCToolChainPath, VSLayout) ||
705      findVCToolChainViaRegistry(VCToolChainPath, VSLayout);
706}
707
708Tool *MSVCToolChain::buildLinker() const {
709  return new tools::visualstudio::Linker(*this);
710}
711
712Tool *MSVCToolChain::buildAssembler() const {
713  if (getTriple().isOSBinFormatMachO())
714    return new tools::darwin::Assembler(*this);
715  getDriver().Diag(clang::diag::err_no_external_assembler);
716  return nullptr;
717}
718
719bool MSVCToolChain::IsIntegratedAssemblerDefault() const {
720  return true;
721}
722
723bool MSVCToolChain::IsUnwindTablesDefault(const ArgList &Args) const {
724  // Don't emit unwind tables by default for MachO targets.
725  if (getTriple().isOSBinFormatMachO())
726    return false;
727
728  // All non-x86_32 Windows targets require unwind tables. However, LLVM
729  // doesn't know how to generate them for all targets, so only enable
730  // the ones that are actually implemented.
731  return getArch() == llvm::Triple::x86_64 ||
732         getArch() == llvm::Triple::aarch64;
733}
734
735bool MSVCToolChain::isPICDefault() const {
736  return getArch() == llvm::Triple::x86_64;
737}
738
739bool MSVCToolChain::isPIEDefault() const {
740  return false;
741}
742
743bool MSVCToolChain::isPICDefaultForced() const {
744  return getArch() == llvm::Triple::x86_64;
745}
746
747void MSVCToolChain::AddCudaIncludeArgs(const ArgList &DriverArgs,
748                                       ArgStringList &CC1Args) const {
749  CudaInstallation.AddCudaIncludeArgs(DriverArgs, CC1Args);
750}
751
752void MSVCToolChain::printVerboseInfo(raw_ostream &OS) const {
753  CudaInstallation.print(OS);
754}
755
756// Windows SDKs and VC Toolchains group their contents into subdirectories based
757// on the target architecture. This function converts an llvm::Triple::ArchType
758// to the corresponding subdirectory name.
759static const char *llvmArchToWindowsSDKArch(llvm::Triple::ArchType Arch) {
760  using ArchType = llvm::Triple::ArchType;
761  switch (Arch) {
762  case ArchType::x86:
763    return "x86";
764  case ArchType::x86_64:
765    return "x64";
766  case ArchType::arm:
767    return "arm";
768  case ArchType::aarch64:
769    return "arm64";
770  default:
771    return "";
772  }
773}
774
775// Similar to the above function, but for Visual Studios before VS2017.
776static const char *llvmArchToLegacyVCArch(llvm::Triple::ArchType Arch) {
777  using ArchType = llvm::Triple::ArchType;
778  switch (Arch) {
779  case ArchType::x86:
780    // x86 is default in legacy VC toolchains.
781    // e.g. x86 libs are directly in /lib as opposed to /lib/x86.
782    return "";
783  case ArchType::x86_64:
784    return "amd64";
785  case ArchType::arm:
786    return "arm";
787  case ArchType::aarch64:
788    return "arm64";
789  default:
790    return "";
791  }
792}
793
794// Similar to the above function, but for DevDiv internal builds.
795static const char *llvmArchToDevDivInternalArch(llvm::Triple::ArchType Arch) {
796  using ArchType = llvm::Triple::ArchType;
797  switch (Arch) {
798  case ArchType::x86:
799    return "i386";
800  case ArchType::x86_64:
801    return "amd64";
802  case ArchType::arm:
803    return "arm";
804  case ArchType::aarch64:
805    return "arm64";
806  default:
807    return "";
808  }
809}
810
811// Get the path to a specific subdirectory in the current toolchain for
812// a given target architecture.
813// VS2017 changed the VC toolchain layout, so this should be used instead
814// of hardcoding paths.
815std::string
816MSVCToolChain::getSubDirectoryPath(SubDirectoryType Type,
817                                   llvm::Triple::ArchType TargetArch) const {
818  const char *SubdirName;
819  const char *IncludeName;
820  switch (VSLayout) {
821  case ToolsetLayout::OlderVS:
822    SubdirName = llvmArchToLegacyVCArch(TargetArch);
823    IncludeName = "include";
824    break;
825  case ToolsetLayout::VS2017OrNewer:
826    SubdirName = llvmArchToWindowsSDKArch(TargetArch);
827    IncludeName = "include";
828    break;
829  case ToolsetLayout::DevDivInternal:
830    SubdirName = llvmArchToDevDivInternalArch(TargetArch);
831    IncludeName = "inc";
832    break;
833  }
834
835  llvm::SmallString<256> Path(VCToolChainPath);
836  switch (Type) {
837  case SubDirectoryType::Bin:
838    if (VSLayout == ToolsetLayout::VS2017OrNewer) {
839      const bool HostIsX64 =
840          llvm::Triple(llvm::sys::getProcessTriple()).isArch64Bit();
841      const char *const HostName = HostIsX64 ? "HostX64" : "HostX86";
842      llvm::sys::path::append(Path, "bin", HostName, SubdirName);
843    } else { // OlderVS or DevDivInternal
844      llvm::sys::path::append(Path, "bin", SubdirName);
845    }
846    break;
847  case SubDirectoryType::Include:
848    llvm::sys::path::append(Path, IncludeName);
849    break;
850  case SubDirectoryType::Lib:
851    llvm::sys::path::append(Path, "lib", SubdirName);
852    break;
853  }
854  return Path.str();
855}
856
857#ifdef _WIN32
858static bool readFullStringValue(HKEY hkey, const char *valueName,
859                                std::string &value) {
860  std::wstring WideValueName;
861  if (!llvm::ConvertUTF8toWide(valueName, WideValueName))
862    return false;
863
864  DWORD result = 0;
865  DWORD valueSize = 0;
866  DWORD type = 0;
867  // First just query for the required size.
868  result = RegQueryValueExW(hkey, WideValueName.c_str(), NULL, &type, NULL,
869                            &valueSize);
870  if (result != ERROR_SUCCESS || type != REG_SZ || !valueSize)
871    return false;
872  std::vector<BYTE> buffer(valueSize);
873  result = RegQueryValueExW(hkey, WideValueName.c_str(), NULL, NULL, &buffer[0],
874                            &valueSize);
875  if (result == ERROR_SUCCESS) {
876    std::wstring WideValue(reinterpret_cast<const wchar_t *>(buffer.data()),
877                           valueSize / sizeof(wchar_t));
878    if (valueSize && WideValue.back() == L'\0') {
879      WideValue.pop_back();
880    }
881    // The destination buffer must be empty as an invariant of the conversion
882    // function; but this function is sometimes called in a loop that passes in
883    // the same buffer, however. Simply clear it out so we can overwrite it.
884    value.clear();
885    return llvm::convertWideToUTF8(WideValue, value);
886  }
887  return false;
888}
889#endif
890
891/// Read registry string.
892/// This also supports a means to look for high-versioned keys by use
893/// of a $VERSION placeholder in the key path.
894/// $VERSION in the key path is a placeholder for the version number,
895/// causing the highest value path to be searched for and used.
896/// I.e. "SOFTWARE\\Microsoft\\VisualStudio\\$VERSION".
897/// There can be additional characters in the component.  Only the numeric
898/// characters are compared.  This function only searches HKLM.
899static bool getSystemRegistryString(const char *keyPathconst char *valueName,
900                                    std::string &valuestd::string *phValue) {
901#ifndef _WIN32
902  return false;
903#else
904  HKEY hRootKey = HKEY_LOCAL_MACHINE;
905  HKEY hKey = NULL;
906  long lResult;
907  bool returnValue = false;
908
909  const char *placeHolder = strstr(keyPath, "$VERSION");
910  std::string bestName;
911  // If we have a $VERSION placeholder, do the highest-version search.
912  if (placeHolder) {
913    const char *keyEnd = placeHolder - 1;
914    const char *nextKey = placeHolder;
915    // Find end of previous key.
916    while ((keyEnd > keyPath) && (*keyEnd != '\\'))
917      keyEnd--;
918    // Find end of key containing $VERSION.
919    while (*nextKey && (*nextKey != '\\'))
920      nextKey++;
921    size_t partialKeyLength = keyEnd - keyPath;
922    char partialKey[256];
923    if (partialKeyLength >= sizeof(partialKey))
924      partialKeyLength = sizeof(partialKey) - 1;
925    strncpy(partialKey, keyPath, partialKeyLength);
926    partialKey[partialKeyLength] = '\0';
927    HKEY hTopKey = NULL;
928    lResult = RegOpenKeyExA(hRootKey, partialKey, 0, KEY_READ | KEY_WOW64_32KEY,
929                            &hTopKey);
930    if (lResult == ERROR_SUCCESS) {
931      char keyName[256];
932      double bestValue = 0.0;
933      DWORD index, size = sizeof(keyName) - 1;
934      for (index = 0; RegEnumKeyExA(hTopKey, index, keyName, &size, NULL, NULL,
935                                    NULL, NULL) == ERROR_SUCCESS;
936           index++) {
937        const char *sp = keyName;
938        while (*sp && !isDigit(*sp))
939          sp++;
940        if (!*sp)
941          continue;
942        const char *ep = sp + 1;
943        while (*ep && (isDigit(*ep) || (*ep == '.')))
944          ep++;
945        char numBuf[32];
946        strncpy(numBuf, sp, sizeof(numBuf) - 1);
947        numBuf[sizeof(numBuf) - 1] = '\0';
948        double dvalue = strtod(numBuf, NULL);
949        if (dvalue > bestValue) {
950          // Test that InstallDir is indeed there before keeping this index.
951          // Open the chosen key path remainder.
952          bestName = keyName;
953          // Append rest of key.
954          bestName.append(nextKey);
955          lResult = RegOpenKeyExA(hTopKey, bestName.c_str(), 0,
956                                  KEY_READ | KEY_WOW64_32KEY, &hKey);
957          if (lResult == ERROR_SUCCESS) {
958            if (readFullStringValue(hKey, valueName, value)) {
959              bestValue = dvalue;
960              if (phValue)
961                *phValue = bestName;
962              returnValue = true;
963            }
964            RegCloseKey(hKey);
965          }
966        }
967        size = sizeof(keyName) - 1;
968      }
969      RegCloseKey(hTopKey);
970    }
971  } else {
972    lResult =
973        RegOpenKeyExA(hRootKey, keyPath, 0, KEY_READ | KEY_WOW64_32KEY, &hKey);
974    if (lResult == ERROR_SUCCESS) {
975      if (readFullStringValue(hKey, valueName, value))
976        returnValue = true;
977      if (phValue)
978        phValue->clear();
979      RegCloseKey(hKey);
980    }
981  }
982  return returnValue;
983#endif // _WIN32
984}
985
986// Find the most recent version of Universal CRT or Windows 10 SDK.
987// vcvarsqueryregistry.bat from Visual Studio 2015 sorts entries in the include
988// directory by name and uses the last one of the list.
989// So we compare entry names lexicographically to find the greatest one.
990static bool getWindows10SDKVersionFromPath(const std::string &SDKPath,
991                                           std::string &SDKVersion) {
992  SDKVersion.clear();
993
994  std::error_code EC;
995  llvm::SmallString<128IncludePath(SDKPath);
996  llvm::sys::path::append(IncludePath, "Include");
997  for (llvm::sys::fs::directory_iterator DirIt(IncludePath, EC), DirEnd;
998       DirIt != DirEnd && !EC; DirIt.increment(EC)) {
999    if (!llvm::sys::fs::is_directory(DirIt->path()))
1000      continue;
1001    StringRef CandidateName = llvm::sys::path::filename(DirIt->path());
1002    // If WDK is installed, there could be subfolders like "wdf" in the
1003    // "Include" directory.
1004    // Allow only directories which names start with "10.".
1005    if (!CandidateName.startswith("10."))
1006      continue;
1007    if (CandidateName > SDKVersion)
1008      SDKVersion = CandidateName;
1009  }
1010
1011  return !SDKVersion.empty();
1012}
1013
1014/// Get Windows SDK installation directory.
1015static bool getWindowsSDKDir(std::string &Pathint &Major,
1016                             std::string &WindowsSDKIncludeVersion,
1017                             std::string &WindowsSDKLibVersion) {
1018  std::string RegistrySDKVersion;
1019  // Try the Windows registry.
1020  if (!getSystemRegistryString(
1021          "SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\$VERSION",
1022          "InstallationFolder"Path, &RegistrySDKVersion))
1023    return false;
1024  if (Path.empty() || RegistrySDKVersion.empty())
1025    return false;
1026
1027  WindowsSDKIncludeVersion.clear();
1028  WindowsSDKLibVersion.clear();
1029  Major = 0;
1030  std::sscanf(RegistrySDKVersion.c_str(), "v%d.", &Major);
1031  if (Major <= 7)
1032    return true;
1033  if (Major == 8) {
1034    // Windows SDK 8.x installs libraries in a folder whose names depend on the
1035    // version of the OS you're targeting.  By default choose the newest, which
1036    // usually corresponds to the version of the OS you've installed the SDK on.
1037    const char *Tests[] = {"winv6.3""win8""win7"};
1038    for (const char *Test : Tests) {
1039      llvm::SmallString<128TestPath(Path);
1040      llvm::sys::path::append(TestPath, "Lib", Test);
1041      if (llvm::sys::fs::exists(TestPath.c_str())) {
1042        WindowsSDKLibVersion = Test;
1043        break;
1044      }
1045    }
1046    return !WindowsSDKLibVersion.empty();
1047  }
1048  if (Major == 10) {
1049    if (!getWindows10SDKVersionFromPath(PathWindowsSDKIncludeVersion))
1050      return false;
1051    WindowsSDKLibVersion = WindowsSDKIncludeVersion;
1052    return true;
1053  }
1054  // Unsupported SDK version
1055  return false;
1056}
1057
1058// Gets the library path required to link against the Windows SDK.
1059bool MSVCToolChain::getWindowsSDKLibraryPath(std::string &path) const {
1060  std::string sdkPath;
1061  int sdkMajor = 0;
1062  std::string windowsSDKIncludeVersion;
1063  std::string windowsSDKLibVersion;
1064
1065  path.clear();
1066  if (!getWindowsSDKDir(sdkPath, sdkMajor, windowsSDKIncludeVersion,
1067                        windowsSDKLibVersion))
1068    return false;
1069
1070  llvm::SmallString<128> libPath(sdkPath);
1071  llvm::sys::path::append(libPath, "Lib");
1072  if (sdkMajor >= 8) {
1073    llvm::sys::path::append(libPath, windowsSDKLibVersion, "um",
1074                            llvmArchToWindowsSDKArch(getArch()));
1075  } else {
1076    switch (getArch()) {
1077    // In Windows SDK 7.x, x86 libraries are directly in the Lib folder.
1078    case llvm::Triple::x86:
1079      break;
1080    case llvm::Triple::x86_64:
1081      llvm::sys::path::append(libPath, "x64");
1082      break;
1083    case llvm::Triple::arm:
1084      // It is not necessary to link against Windows SDK 7.x when targeting ARM.
1085      return false;
1086    default:
1087      return false;
1088    }
1089  }
1090
1091  path = libPath.str();
1092  return true;
1093}
1094
1095// Check if the Include path of a specified version of Visual Studio contains
1096// specific header files. If not, they are probably shipped with Universal CRT.
1097bool MSVCToolChain::useUniversalCRT() const {
1098  llvm::SmallString<128> TestPath(
1099      getSubDirectoryPath(SubDirectoryType::Include));
1100  llvm::sys::path::append(TestPath, "stdlib.h");
1101  return !llvm::sys::fs::exists(TestPath);
1102}
1103
1104static bool getUniversalCRTSdkDir(std::string &Pathstd::string &UCRTVersion) {
1105  // vcvarsqueryregistry.bat for Visual Studio 2015 queries the registry
1106  // for the specific key "KitsRoot10". So do we.
1107  if (!getSystemRegistryString(
1108          "SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots""KitsRoot10",
1109          Pathnullptr))
1110    return false;
1111
1112  return getWindows10SDKVersionFromPath(PathUCRTVersion);
1113}
1114
1115bool MSVCToolChain::getUniversalCRTLibraryPath(std::string &Path) const {
1116  std::string UniversalCRTSdkPath;
1117  std::string UCRTVersion;
1118
1119  Path.clear();
1120  if (!getUniversalCRTSdkDir(UniversalCRTSdkPath, UCRTVersion))
1121    return false;
1122
1123  StringRef ArchName = llvmArchToWindowsSDKArch(getArch());
1124  if (ArchName.empty())
1125    return false;
1126
1127  llvm::SmallString<128> LibPath(UniversalCRTSdkPath);
1128  llvm::sys::path::append(LibPath, "Lib", UCRTVersion, "ucrt", ArchName);
1129
1130  Path = LibPath.str();
1131  return true;
1132}
1133
1134static VersionTuple getMSVCVersionFromTriple(const llvm::Triple &Triple) {
1135  unsigned MajorMinorMicro;
1136  Triple.getEnvironmentVersion(Major, Minor, Micro);
1137  if (Major || Minor || Micro)
1138    return VersionTuple(Major, Minor, Micro);
1139  return VersionTuple();
1140}
1141
1142static VersionTuple getMSVCVersionFromExe(const std::string &BinDir) {
1143  VersionTuple Version;
1144#ifdef _WIN32
1145  SmallString<128> ClExe(BinDir);
1146  llvm::sys::path::append(ClExe, "cl.exe");
1147
1148  std::wstring ClExeWide;
1149  if (!llvm::ConvertUTF8toWide(ClExe.c_str(), ClExeWide))
1150    return Version;
1151
1152  const DWORD VersionSize = ::GetFileVersionInfoSizeW(ClExeWide.c_str(),
1153                                                      nullptr);
1154  if (VersionSize == 0)
1155    return Version;
1156
1157  SmallVector<uint8_t, 4 * 1024> VersionBlock(VersionSize);
1158  if (!::GetFileVersionInfoW(ClExeWide.c_str(), 0, VersionSize,
1159                             VersionBlock.data()))
1160    return Version;
1161
1162  VS_FIXEDFILEINFO *FileInfo = nullptr;
1163  UINT FileInfoSize = 0;
1164  if (!::VerQueryValueW(VersionBlock.data(), L"\\",
1165                        reinterpret_cast<LPVOID *>(&FileInfo), &FileInfoSize) ||
1166      FileInfoSize < sizeof(*FileInfo))
1167    return Version;
1168
1169  const unsigned Major = (FileInfo->dwFileVersionMS >> 16) & 0xFFFF;
1170  const unsigned Minor = (FileInfo->dwFileVersionMS      ) & 0xFFFF;
1171  const unsigned Micro = (FileInfo->dwFileVersionLS >> 16) & 0xFFFF;
1172
1173  Version = VersionTuple(Major, Minor, Micro);
1174#endif
1175  return Version;
1176}
1177
1178void MSVCToolChain::AddSystemIncludeWithSubfolder(
1179    const ArgList &DriverArgs, ArgStringList &CC1Args,
1180    const std::string &folder, const Twine &subfolder1, const Twine &subfolder2,
1181    const Twine &subfolder3) const {
1182  llvm::SmallString<128> path(folder);
1183  llvm::sys::path::append(path, subfolder1, subfolder2, subfolder3);
1184  addSystemInclude(DriverArgs, CC1Args, path);
1185}
1186
1187void MSVCToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
1188                                              ArgStringList &CC1Args) const {
1189  if (DriverArgs.hasArg(options::OPT_nostdinc))
1190    return;
1191
1192  if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
1193    AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, getDriver().ResourceDir,
1194                                  "include");
1195  }
1196
1197  // Add %INCLUDE%-like directories from the -imsvc flag.
1198  for (const auto &Path : DriverArgs.getAllArgValues(options::OPT__SLASH_imsvc))
1199    addSystemInclude(DriverArgs, CC1Args, Path);
1200
1201  if (DriverArgs.hasArg(options::OPT_nostdlibinc))
1202    return;
1203
1204  // Honor %INCLUDE%. It should know essential search paths with vcvarsall.bat.
1205  if (llvm::Optional<std::string> cl_include_dir =
1206          llvm::sys::Process::GetEnv("INCLUDE")) {
1207    SmallVector<StringRef, 8> Dirs;
1208    StringRef(*cl_include_dir)
1209        .split(Dirs, ";"/*MaxSplit=*/-1/*KeepEmpty=*/false);
1210    for (StringRef Dir : Dirs)
1211      addSystemInclude(DriverArgs, CC1Args, Dir);
1212    if (!Dirs.empty())
1213      return;
1214  }
1215
1216  // When built with access to the proper Windows APIs, try to actually find
1217  // the correct include paths first.
1218  if (!VCToolChainPath.empty()) {
1219    addSystemInclude(DriverArgs, CC1Args,
1220                     getSubDirectoryPath(SubDirectoryType::Include));
1221
1222    if (useUniversalCRT()) {
1223      std::string UniversalCRTSdkPath;
1224      std::string UCRTVersion;
1225      if (getUniversalCRTSdkDir(UniversalCRTSdkPath, UCRTVersion)) {
1226        AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, UniversalCRTSdkPath,
1227                                      "Include", UCRTVersion, "ucrt");
1228      }
1229    }
1230
1231    std::string WindowsSDKDir;
1232    int major;
1233    std::string windowsSDKIncludeVersion;
1234    std::string windowsSDKLibVersion;
1235    if (getWindowsSDKDir(WindowsSDKDir, major, windowsSDKIncludeVersion,
1236                         windowsSDKLibVersion)) {
1237      if (major >= 8) {
1238        // Note: windowsSDKIncludeVersion is empty for SDKs prior to v10.
1239        // Anyway, llvm::sys::path::append is able to manage it.
1240        AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
1241                                      "include", windowsSDKIncludeVersion,
1242                                      "shared");
1243        AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
1244                                      "include", windowsSDKIncludeVersion,
1245                                      "um");
1246        AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
1247                                      "include", windowsSDKIncludeVersion,
1248                                      "winrt");
1249      } else {
1250        AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
1251                                      "include");
1252      }
1253    }
1254
1255    return;
1256  }
1257
1258#if defined(_WIN32)
1259  // As a fallback, select default install paths.
1260  // FIXME: Don't guess drives and paths like this on Windows.
1261  const StringRef Paths[] = {
1262    "C:/Program Files/Microsoft Visual Studio 10.0/VC/include",
1263    "C:/Program Files/Microsoft Visual Studio 9.0/VC/include",
1264    "C:/Program Files/Microsoft Visual Studio 9.0/VC/PlatformSDK/Include",
1265    "C:/Program Files/Microsoft Visual Studio 8/VC/include",
1266    "C:/Program Files/Microsoft Visual Studio 8/VC/PlatformSDK/Include"
1267  };
1268  addSystemIncludes(DriverArgs, CC1Args, Paths);
1269#endif
1270}
1271
1272void MSVCToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
1273                                                 ArgStringList &CC1Args) const {
1274  // FIXME: There should probably be logic here to find libc++ on Windows.
1275}
1276
1277VersionTuple MSVCToolChain::computeMSVCVersion(const Driver *D,
1278                                               const ArgList &Args) const {
1279  bool IsWindowsMSVC = getTriple().isWindowsMSVCEnvironment();
1280  VersionTuple MSVT = ToolChain::computeMSVCVersion(D, Args);
1281  if (MSVT.empty())
1282    MSVT = getMSVCVersionFromTriple(getTriple());
1283  if (MSVT.empty() && IsWindowsMSVC)
1284    MSVT = getMSVCVersionFromExe(getSubDirectoryPath(SubDirectoryType::Bin));
1285  if (MSVT.empty() &&
1286      Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions,
1287                   IsWindowsMSVC)) {
1288    // -fms-compatibility-version=19.11 is default, aka 2017, 15.3
1289    MSVT = VersionTuple(1911);
1290  }
1291  return MSVT;
1292}
1293
1294std::string
1295MSVCToolChain::ComputeEffectiveClangTriple(const ArgList &Args,
1296                                           types::ID InputType) const {
1297  // The MSVC version doesn't care about the architecture, even though it
1298  // may look at the triple internally.
1299  VersionTuple MSVT = computeMSVCVersion(/*D=*/nullptr, Args);
1300  MSVT = VersionTuple(MSVT.getMajor(), MSVT.getMinor().getValueOr(0),
1301                      MSVT.getSubminor().getValueOr(0));
1302
1303  // For the rest of the triple, however, a computed architecture name may
1304  // be needed.
1305  llvm::Triple Triple(ToolChain::ComputeEffectiveClangTriple(Args, InputType));
1306  if (Triple.getEnvironment() == llvm::Triple::MSVC) {
1307    StringRef ObjFmt = Triple.getEnvironmentName().split('-').second;
1308    if (ObjFmt.empty())
1309      Triple.setEnvironmentName((Twine("msvc") + MSVT.getAsString()).str());
1310    else
1311      Triple.setEnvironmentName(
1312          (Twine("msvc") + MSVT.getAsString() + Twine('-') + ObjFmt).str());
1313  }
1314  return Triple.getTriple();
1315}
1316
1317SanitizerMask MSVCToolChain::getSupportedSanitizers() const {
1318  SanitizerMask Res = ToolChain::getSupportedSanitizers();
1319  Res |= SanitizerKind::Address;
1320  Res |= SanitizerKind::Fuzzer;
1321  Res |= SanitizerKind::FuzzerNoLink;
1322  Res &= ~SanitizerKind::CFIMFCall;
1323  return Res;
1324}
1325
1326static void TranslateOptArg(Arg *Allvm::opt::DerivedArgList &DAL,
1327                            bool SupportsForcingFramePointer,
1328                            const char *ExpandCharconst OptTable &Opts) {
1329  getOption().matches(options..OPT__SLASH_O)", "/home/seafit/code_projects/clang_source/clang/lib/Driver/ToolChains/MSVC.cpp", 1329, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(A->getOption().matches(options::OPT__SLASH_O));
1330
1331  StringRef OptStr = A->getValue();
1332  for (size_t I = 0, E = OptStr.size(); I != E; ++I) {
1333    const char &OptChar = *(OptStr.data() + I);
1334    switch (OptChar) {
1335    default:
1336      break;
1337    case '1':
1338    case '2':
1339    case 'x':
1340    case 'd':
1341      // Ignore /O[12xd] flags that aren't the last one on the command line.
1342      // Only the last one gets expanded.
1343      if (&OptChar != ExpandChar) {
1344        A->claim();
1345        break;
1346      }
1347      if (OptChar == 'd') {
1348        DAL.AddFlagArg(A, Opts.getOption(options::OPT_O0));
1349      } else {
1350        if (OptChar == '1') {
1351          DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "s");
1352        } else if (OptChar == '2' || OptChar == 'x') {
1353          DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
1354          DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "2");
1355        }
1356        if (SupportsForcingFramePointer &&
1357            !DAL.hasArgNoClaim(options::OPT_fno_omit_frame_pointer))
1358          DAL.AddFlagArg(A, Opts.getOption(options::OPT_fomit_frame_pointer));
1359        if (OptChar == '1' || OptChar == '2')
1360          DAL.AddFlagArg(A, Opts.getOption(options::OPT_ffunction_sections));
1361      }
1362      break;
1363    case 'b':
1364      if (I + 1 != E && isdigit(OptStr[I + 1])) {
1365        switch (OptStr[I + 1]) {
1366        case '0':
1367          DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_inline));
1368          break;
1369        case '1':
1370          DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_hint_functions));
1371          break;
1372        case '2':
1373          DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_functions));
1374          break;
1375        }
1376        ++I;
1377      }
1378      break;
1379    case 'g':
1380      A->claim();
1381      break;
1382    case 'i':
1383      if (I + 1 != E && OptStr[I + 1] == '-') {
1384        ++I;
1385        DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_builtin));
1386      } else {
1387        DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
1388      }
1389      break;
1390    case 's':
1391      DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "s");
1392      break;
1393    case 't':
1394      DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "2");
1395      break;
1396    case 'y': {
1397      bool OmitFramePointer = true;
1398      if (I + 1 != E && OptStr[I + 1] == '-') {
1399        OmitFramePointer = false;
1400        ++I;
1401      }
1402      if (SupportsForcingFramePointer) {
1403        if (OmitFramePointer)
1404          DAL.AddFlagArg(A,
1405                         Opts.getOption(options::OPT_fomit_frame_pointer));
1406        else
1407          DAL.AddFlagArg(
1408              A, Opts.getOption(options::OPT_fno_omit_frame_pointer));
1409      } else {
1410        // Don't warn about /Oy- in x86-64 builds (where
1411        // SupportsForcingFramePointer is false).  The flag having no effect
1412        // there is a compiler-internal optimization, and people shouldn't have
1413        // to special-case their build files for x86-64 clang-cl.
1414        A->claim();
1415      }
1416      break;
1417    }
1418    }
1419  }
1420}
1421
1422static void TranslateDArg(Arg *Allvm::opt::DerivedArgList &DAL,
1423                          const OptTable &Opts) {
1424  getOption().matches(options..OPT_D)", "/home/seafit/code_projects/clang_source/clang/lib/Driver/ToolChains/MSVC.cpp", 1424, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(A->getOption().matches(options::OPT_D));
1425
1426  StringRef Val = A->getValue();
1427  size_t Hash = Val.find('#');
1428  if (Hash == StringRef::npos || Hash > Val.find('=')) {
1429    DAL.append(A);
1430    return;
1431  }
1432
1433  std::string NewVal = Val;
1434  NewVal[Hash] = '=';
1435  DAL.AddJoinedArg(A, Opts.getOption(options::OPT_D), NewVal);
1436}
1437
1438llvm::opt::DerivedArgList *
1439MSVCToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args,
1440                             StringRef BoundArch, Action::OffloadKind) const {
1441  DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
1442  const OptTable &Opts = getDriver().getOpts();
1443
1444  // /Oy and /Oy- don't have an effect on X86-64
1445  bool SupportsForcingFramePointer = getArch() != llvm::Triple::x86_64;
1446
1447  // The -O[12xd] flag actually expands to several flags.  We must desugar the
1448  // flags so that options embedded can be negated.  For example, the '-O2' flag
1449  // enables '-Oy'.  Expanding '-O2' into its constituent flags allows us to
1450  // correctly handle '-O2 -Oy-' where the trailing '-Oy-' disables a single
1451  // aspect of '-O2'.
1452  //
1453  // Note that this expansion logic only applies to the *last* of '[12xd]'.
1454
1455  // First step is to search for the character we'd like to expand.
1456  const char *ExpandChar = nullptr;
1457  for (Arg *A : Args.filtered(options::OPT__SLASH_O)) {
1458    StringRef OptStr = A->getValue();
1459    for (size_t I = 0, E = OptStr.size(); I != E; ++I) {
1460      char OptChar = OptStr[I];
1461      char PrevChar = I > 0 ? OptStr[I - 1] : '0';
1462      if (PrevChar == 'b') {
1463        // OptChar does not expand; it's an argument to the previous char.
1464        continue;
1465      }
1466      if (OptChar == '1' || OptChar == '2' || OptChar == 'x' || OptChar == 'd')
1467        ExpandChar = OptStr.data() + I;
1468    }
1469  }
1470
1471  for (Arg *A : Args) {
1472    if (A->getOption().matches(options::OPT__SLASH_O)) {
1473      // The -O flag actually takes an amalgam of other options.  For example,
1474      // '/Ogyb2' is equivalent to '/Og' '/Oy' '/Ob2'.
1475      TranslateOptArg(A, *DAL, SupportsForcingFramePointer, ExpandChar, Opts);
1476    } else if (A->getOption().matches(options::OPT_D)) {
1477      // Translate -Dfoo#bar into -Dfoo=bar.
1478      TranslateDArg(A, *DAL, Opts);
1479    } else {
1480      DAL->append(A);
1481    }
1482  }
1483
1484  return DAL;
1485}
1486