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