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