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