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