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 bool &IsVS2017OrNewer) { 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 IsVS2017OrNewer = true; 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 IsVS2017OrNewer = false; 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 if (llvm::sys::path::filename(ParentPath) == "VC") { 138 Path = ParentPath; 139 IsVS2017OrNewer = false; 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 IsVS2017OrNewer = true; 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 bool &IsVS2017OrNewer) { 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 IsVS2017OrNewer = true; 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 bool &IsVS2017OrNewer) { 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 IsVS2017OrNewer = false; 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 bool DLL = Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd, 359 options::OPT_shared); 360 if (DLL) { 361 CmdArgs.push_back(Args.MakeArgString("-dll")); 362 363 SmallString<128> ImplibName(Output.getFilename()); 364 llvm::sys::path::replace_extension(ImplibName, "lib"); 365 CmdArgs.push_back(Args.MakeArgString(std::string("-implib:") + ImplibName)); 366 } 367 368 if (TC.getSanitizerArgs().needsAsanRt()) { 369 CmdArgs.push_back(Args.MakeArgString("-debug")); 370 CmdArgs.push_back(Args.MakeArgString("-incremental:no")); 371 if (TC.getSanitizerArgs().needsSharedAsanRt() || 372 Args.hasArg(options::OPT__SLASH_MD, options::OPT__SLASH_MDd)) { 373 for (const auto &Lib : {"asan_dynamic", "asan_dynamic_runtime_thunk"}) 374 CmdArgs.push_back(TC.getCompilerRTArgString(Args, Lib)); 375 // Make sure the dynamic runtime thunk is not optimized out at link time 376 // to ensure proper SEH handling. 377 CmdArgs.push_back(Args.MakeArgString( 378 TC.getArch() == llvm::Triple::x86 379 ? "-include:___asan_seh_interceptor" 380 : "-include:__asan_seh_interceptor")); 381 // Make sure the linker consider all object files from the dynamic runtime 382 // thunk. 383 CmdArgs.push_back(Args.MakeArgString(std::string("-wholearchive:") + 384 TC.getCompilerRT(Args, "asan_dynamic_runtime_thunk"))); 385 } else if (DLL) { 386 CmdArgs.push_back(TC.getCompilerRTArgString(Args, "asan_dll_thunk")); 387 } else { 388 for (const auto &Lib : {"asan", "asan_cxx"}) { 389 CmdArgs.push_back(TC.getCompilerRTArgString(Args, Lib)); 390 // Make sure the linker consider all object files from the static lib. 391 // This is necessary because instrumented dlls need access to all the 392 // interface exported by the static lib in the main executable. 393 CmdArgs.push_back(Args.MakeArgString(std::string("-wholearchive:") + 394 TC.getCompilerRT(Args, Lib))); 395 } 396 } 397 } 398 399 Args.AddAllArgValues(CmdArgs, options::OPT__SLASH_link); 400 401 if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ, 402 options::OPT_fno_openmp, false)) { 403 CmdArgs.push_back("-nodefaultlib:vcomp.lib"); 404 CmdArgs.push_back("-nodefaultlib:vcompd.lib"); 405 CmdArgs.push_back(Args.MakeArgString(std::string("-libpath:") + 406 TC.getDriver().Dir + "/../lib")); 407 switch (TC.getDriver().getOpenMPRuntime(Args)) { 408 case Driver::OMPRT_OMP: 409 CmdArgs.push_back("-defaultlib:libomp.lib"); 410 break; 411 case Driver::OMPRT_IOMP5: 412 CmdArgs.push_back("-defaultlib:libiomp5md.lib"); 413 break; 414 case Driver::OMPRT_GOMP: 415 break; 416 case Driver::OMPRT_Unknown: 417 // Already diagnosed. 418 break; 419 } 420 } 421 422 // Add compiler-rt lib in case if it was explicitly 423 // specified as an argument for --rtlib option. 424 if (!Args.hasArg(options::OPT_nostdlib)) { 425 AddRunTimeLibs(TC, TC.getDriver(), CmdArgs, Args); 426 } 427 428 // Add filenames, libraries, and other linker inputs. 429 for (const auto &Input : Inputs) { 430 if (Input.isFilename()) { 431 CmdArgs.push_back(Input.getFilename()); 432 continue; 433 } 434 435 const Arg &A = Input.getInputArg(); 436 437 // Render -l options differently for the MSVC linker. 438 if (A.getOption().matches(options::OPT_l)) { 439 StringRef Lib = A.getValue(); 440 const char *LinkLibArg; 441 if (Lib.endswith(".lib")) 442 LinkLibArg = Args.MakeArgString(Lib); 443 else 444 LinkLibArg = Args.MakeArgString(Lib + ".lib"); 445 CmdArgs.push_back(LinkLibArg); 446 continue; 447 } 448 449 // Otherwise, this is some other kind of linker input option like -Wl, -z, 450 // or -L. Render it, even if MSVC doesn't understand it. 451 A.renderAsInput(Args, CmdArgs); 452 } 453 454 TC.addProfileRTLibs(Args, CmdArgs); 455 456 std::vector<const char *> Environment; 457 458 // We need to special case some linker paths. In the case of lld, we need to 459 // translate 'lld' into 'lld-link', and in the case of the regular msvc 460 // linker, we need to use a special search algorithm. 461 llvm::SmallString<128> linkPath; 462 StringRef Linker = Args.getLastArgValue(options::OPT_fuse_ld_EQ, "link"); 463 if (Linker.equals_lower("lld")) 464 Linker = "lld-link"; 465 466 if (Linker.equals_lower("link")) { 467 // If we're using the MSVC linker, it's not sufficient to just use link 468 // from the program PATH, because other environments like GnuWin32 install 469 // their own link.exe which may come first. 470 linkPath = FindVisualStudioExecutable(TC, "link.exe"); 471 472 #ifdef USE_WIN32 473 // When cross-compiling with VS2017 or newer, link.exe expects to have 474 // its containing bin directory at the top of PATH, followed by the 475 // native target bin directory. 476 // e.g. when compiling for x86 on an x64 host, PATH should start with: 477 // /bin/HostX64/x86;/bin/HostX64/x64 478 if (TC.getIsVS2017OrNewer() && 479 llvm::Triple(llvm::sys::getProcessTriple()).getArch() != TC.getArch()) { 480 auto HostArch = llvm::Triple(llvm::sys::getProcessTriple()).getArch(); 481 482 auto EnvBlockWide = 483 std::unique_ptr<wchar_t[], decltype(&FreeEnvironmentStringsW)>( 484 GetEnvironmentStringsW(), FreeEnvironmentStringsW); 485 if (!EnvBlockWide) 486 goto SkipSettingEnvironment; 487 488 size_t EnvCount = 0; 489 size_t EnvBlockLen = 0; 490 while (EnvBlockWide[EnvBlockLen] != L'\0') { 491 ++EnvCount; 492 EnvBlockLen += std::wcslen(&EnvBlockWide[EnvBlockLen]) + 493 1 /*string null-terminator*/; 494 } 495 ++EnvBlockLen; // add the block null-terminator 496 497 std::string EnvBlock; 498 if (!llvm::convertUTF16ToUTF8String( 499 llvm::ArrayRef<char>(reinterpret_cast<char *>(EnvBlockWide.get()), 500 EnvBlockLen * sizeof(EnvBlockWide[0])), 501 EnvBlock)) 502 goto SkipSettingEnvironment; 503 504 Environment.reserve(EnvCount); 505 506 // Now loop over each string in the block and copy them into the 507 // environment vector, adjusting the PATH variable as needed when we 508 // find it. 509 for (const char *Cursor = EnvBlock.data(); *Cursor != '\0';) { 510 llvm::StringRef EnvVar(Cursor); 511 if (EnvVar.startswith_lower("path=")) { 512 using SubDirectoryType = toolchains::MSVCToolChain::SubDirectoryType; 513 constexpr size_t PrefixLen = 5; // strlen("path=") 514 Environment.push_back(Args.MakeArgString( 515 EnvVar.substr(0, PrefixLen) + 516 TC.getSubDirectoryPath(SubDirectoryType::Bin) + 517 llvm::Twine(llvm::sys::EnvPathSeparator) + 518 TC.getSubDirectoryPath(SubDirectoryType::Bin, HostArch) + 519 (EnvVar.size() > PrefixLen 520 ? llvm::Twine(llvm::sys::EnvPathSeparator) + 521 EnvVar.substr(PrefixLen) 522 : ""))); 523 } else { 524 Environment.push_back(Args.MakeArgString(EnvVar)); 525 } 526 Cursor += EnvVar.size() + 1 /*null-terminator*/; 527 } 528 } 529 SkipSettingEnvironment:; 530 #endif 531 } else { 532 linkPath = TC.GetProgramPath(Linker.str().c_str()); 533 } 534 535 auto LinkCmd = llvm::make_unique<Command>( 536 JA, *this, Args.MakeArgString(linkPath), CmdArgs, Inputs); 537 if (!Environment.empty()) 538 LinkCmd->setEnvironment(Environment); 539 C.addCommand(std::move(LinkCmd)); 540 } 541 542 void visualstudio::Compiler::ConstructJob(Compilation &C, const JobAction &JA, 543 const InputInfo &Output, 544 const InputInfoList &Inputs, 545 const ArgList &Args, 546 const char *LinkingOutput) const { 547 C.addCommand(GetCommand(C, JA, Output, Inputs, Args, LinkingOutput)); 548 } 549 550 std::unique_ptr<Command> visualstudio::Compiler::GetCommand( 551 Compilation &C, const JobAction &JA, const InputInfo &Output, 552 const InputInfoList &Inputs, const ArgList &Args, 553 const char *LinkingOutput) const { 554 ArgStringList CmdArgs; 555 CmdArgs.push_back("/nologo"); 556 CmdArgs.push_back("/c"); // Compile only. 557 CmdArgs.push_back("/W0"); // No warnings. 558 559 // The goal is to be able to invoke this tool correctly based on 560 // any flag accepted by clang-cl. 561 562 // These are spelled the same way in clang and cl.exe,. 563 Args.AddAllArgs(CmdArgs, {options::OPT_D, options::OPT_U, options::OPT_I}); 564 565 // Optimization level. 566 if (Arg *A = Args.getLastArg(options::OPT_fbuiltin, options::OPT_fno_builtin)) 567 CmdArgs.push_back(A->getOption().getID() == options::OPT_fbuiltin ? "/Oi" 568 : "/Oi-"); 569 if (Arg *A = Args.getLastArg(options::OPT_O, options::OPT_O0)) { 570 if (A->getOption().getID() == options::OPT_O0) { 571 CmdArgs.push_back("/Od"); 572 } else { 573 CmdArgs.push_back("/Og"); 574 575 StringRef OptLevel = A->getValue(); 576 if (OptLevel == "s" || OptLevel == "z") 577 CmdArgs.push_back("/Os"); 578 else 579 CmdArgs.push_back("/Ot"); 580 581 CmdArgs.push_back("/Ob2"); 582 } 583 } 584 if (Arg *A = Args.getLastArg(options::OPT_fomit_frame_pointer, 585 options::OPT_fno_omit_frame_pointer)) 586 CmdArgs.push_back(A->getOption().getID() == options::OPT_fomit_frame_pointer 587 ? "/Oy" 588 : "/Oy-"); 589 if (!Args.hasArg(options::OPT_fwritable_strings)) 590 CmdArgs.push_back("/GF"); 591 592 // Flags for which clang-cl has an alias. 593 // FIXME: How can we ensure this stays in sync with relevant clang-cl options? 594 595 if (Args.hasFlag(options::OPT__SLASH_GR_, options::OPT__SLASH_GR, 596 /*default=*/false)) 597 CmdArgs.push_back("/GR-"); 598 599 if (Args.hasFlag(options::OPT__SLASH_GS_, options::OPT__SLASH_GS, 600 /*default=*/false)) 601 CmdArgs.push_back("/GS-"); 602 603 if (Arg *A = Args.getLastArg(options::OPT_ffunction_sections, 604 options::OPT_fno_function_sections)) 605 CmdArgs.push_back(A->getOption().getID() == options::OPT_ffunction_sections 606 ? "/Gy" 607 : "/Gy-"); 608 if (Arg *A = Args.getLastArg(options::OPT_fdata_sections, 609 options::OPT_fno_data_sections)) 610 CmdArgs.push_back( 611 A->getOption().getID() == options::OPT_fdata_sections ? "/Gw" : "/Gw-"); 612 if (Args.hasArg(options::OPT_fsyntax_only)) 613 CmdArgs.push_back("/Zs"); 614 if (Args.hasArg(options::OPT_g_Flag, options::OPT_gline_tables_only, 615 options::OPT__SLASH_Z7)) 616 CmdArgs.push_back("/Z7"); 617 618 std::vector<std::string> Includes = 619 Args.getAllArgValues(options::OPT_include); 620 for (const auto &Include : Includes) 621 CmdArgs.push_back(Args.MakeArgString(std::string("/FI") + Include)); 622 623 // Flags that can simply be passed through. 624 Args.AddAllArgs(CmdArgs, options::OPT__SLASH_LD); 625 Args.AddAllArgs(CmdArgs, options::OPT__SLASH_LDd); 626 Args.AddAllArgs(CmdArgs, options::OPT__SLASH_GX); 627 Args.AddAllArgs(CmdArgs, options::OPT__SLASH_GX_); 628 Args.AddAllArgs(CmdArgs, options::OPT__SLASH_EH); 629 Args.AddAllArgs(CmdArgs, options::OPT__SLASH_Zl); 630 631 // The order of these flags is relevant, so pick the last one. 632 if (Arg *A = Args.getLastArg(options::OPT__SLASH_MD, options::OPT__SLASH_MDd, 633 options::OPT__SLASH_MT, options::OPT__SLASH_MTd)) 634 A->render(Args, CmdArgs); 635 636 // Use MSVC's default threadsafe statics behaviour unless there was a flag. 637 if (Arg *A = Args.getLastArg(options::OPT_fthreadsafe_statics, 638 options::OPT_fno_threadsafe_statics)) { 639 CmdArgs.push_back(A->getOption().getID() == options::OPT_fthreadsafe_statics 640 ? "/Zc:threadSafeInit" 641 : "/Zc:threadSafeInit-"); 642 } 643 644 // Pass through all unknown arguments so that the fallback command can see 645 // them too. 646 Args.AddAllArgs(CmdArgs, options::OPT_UNKNOWN); 647 648 // Input filename. 649 assert(Inputs.size() == 1); 650 const InputInfo &II = Inputs[0]; 651 assert(II.getType() == types::TY_C || II.getType() == types::TY_CXX); 652 CmdArgs.push_back(II.getType() == types::TY_C ? "/Tc" : "/Tp"); 653 if (II.isFilename()) 654 CmdArgs.push_back(II.getFilename()); 655 else 656 II.getInputArg().renderAsInput(Args, CmdArgs); 657 658 // Output filename. 659 assert(Output.getType() == types::TY_Object); 660 const char *Fo = 661 Args.MakeArgString(std::string("/Fo") + Output.getFilename()); 662 CmdArgs.push_back(Fo); 663 664 std::string Exec = FindVisualStudioExecutable(getToolChain(), "cl.exe"); 665 return llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Exec), 666 CmdArgs, Inputs); 667 } 668 669 MSVCToolChain::MSVCToolChain(const Driver &D, const llvm::Triple &Triple, 670 const ArgList &Args) 671 : ToolChain(D, Triple, Args), CudaInstallation(D, Triple, Args) { 672 getProgramPaths().push_back(getDriver().getInstalledDir()); 673 if (getDriver().getInstalledDir() != getDriver().Dir) 674 getProgramPaths().push_back(getDriver().Dir); 675 676 // Check the environment first, since that's probably the user telling us 677 // what they want to use. 678 // Failing that, just try to find the newest Visual Studio version we can 679 // and use its default VC toolchain. 680 findVCToolChainViaEnvironment(VCToolChainPath, IsVS2017OrNewer) || 681 findVCToolChainViaSetupConfig(VCToolChainPath, IsVS2017OrNewer) || 682 findVCToolChainViaRegistry(VCToolChainPath, IsVS2017OrNewer); 683 } 684 685 Tool *MSVCToolChain::buildLinker() const { 686 if (VCToolChainPath.empty()) 687 getDriver().Diag(clang::diag::warn_drv_msvc_not_found); 688 return new tools::visualstudio::Linker(*this); 689 } 690 691 Tool *MSVCToolChain::buildAssembler() const { 692 if (getTriple().isOSBinFormatMachO()) 693 return new tools::darwin::Assembler(*this); 694 getDriver().Diag(clang::diag::err_no_external_assembler); 695 return nullptr; 696 } 697 698 bool MSVCToolChain::IsIntegratedAssemblerDefault() const { 699 return true; 700 } 701 702 bool MSVCToolChain::IsUnwindTablesDefault(const ArgList &Args) const { 703 // Emit unwind tables by default on Win64. All non-x86_32 Windows platforms 704 // such as ARM and PPC actually require unwind tables, but LLVM doesn't know 705 // how to generate them yet. 706 707 // Don't emit unwind tables by default for MachO targets. 708 if (getTriple().isOSBinFormatMachO()) 709 return false; 710 711 return getArch() == llvm::Triple::x86_64; 712 } 713 714 bool MSVCToolChain::isPICDefault() const { 715 return getArch() == llvm::Triple::x86_64; 716 } 717 718 bool MSVCToolChain::isPIEDefault() const { 719 return false; 720 } 721 722 bool MSVCToolChain::isPICDefaultForced() const { 723 return getArch() == llvm::Triple::x86_64; 724 } 725 726 void MSVCToolChain::AddCudaIncludeArgs(const ArgList &DriverArgs, 727 ArgStringList &CC1Args) const { 728 CudaInstallation.AddCudaIncludeArgs(DriverArgs, CC1Args); 729 } 730 731 void MSVCToolChain::printVerboseInfo(raw_ostream &OS) const { 732 CudaInstallation.print(OS); 733 } 734 735 // Windows SDKs and VC Toolchains group their contents into subdirectories based 736 // on the target architecture. This function converts an llvm::Triple::ArchType 737 // to the corresponding subdirectory name. 738 static const char *llvmArchToWindowsSDKArch(llvm::Triple::ArchType Arch) { 739 using ArchType = llvm::Triple::ArchType; 740 switch (Arch) { 741 case ArchType::x86: 742 return "x86"; 743 case ArchType::x86_64: 744 return "x64"; 745 case ArchType::arm: 746 return "arm"; 747 default: 748 return ""; 749 } 750 } 751 752 // Similar to the above function, but for Visual Studios before VS2017. 753 static const char *llvmArchToLegacyVCArch(llvm::Triple::ArchType Arch) { 754 using ArchType = llvm::Triple::ArchType; 755 switch (Arch) { 756 case ArchType::x86: 757 // x86 is default in legacy VC toolchains. 758 // e.g. x86 libs are directly in /lib as opposed to /lib/x86. 759 return ""; 760 case ArchType::x86_64: 761 return "amd64"; 762 case ArchType::arm: 763 return "arm"; 764 default: 765 return ""; 766 } 767 } 768 769 // Get the path to a specific subdirectory in the current toolchain for 770 // a given target architecture. 771 // VS2017 changed the VC toolchain layout, so this should be used instead 772 // of hardcoding paths. 773 std::string 774 MSVCToolChain::getSubDirectoryPath(SubDirectoryType Type, 775 llvm::Triple::ArchType TargetArch) const { 776 llvm::SmallString<256> Path(VCToolChainPath); 777 switch (Type) { 778 case SubDirectoryType::Bin: 779 if (IsVS2017OrNewer) { 780 bool HostIsX64 = 781 llvm::Triple(llvm::sys::getProcessTriple()).isArch64Bit(); 782 llvm::sys::path::append(Path, "bin", (HostIsX64 ? "HostX64" : "HostX86"), 783 llvmArchToWindowsSDKArch(TargetArch)); 784 785 } else { 786 llvm::sys::path::append(Path, "bin", llvmArchToLegacyVCArch(TargetArch)); 787 } 788 break; 789 case SubDirectoryType::Include: 790 llvm::sys::path::append(Path, "include"); 791 break; 792 case SubDirectoryType::Lib: 793 llvm::sys::path::append( 794 Path, "lib", IsVS2017OrNewer ? llvmArchToWindowsSDKArch(TargetArch) 795 : llvmArchToLegacyVCArch(TargetArch)); 796 break; 797 } 798 return Path.str(); 799 } 800 801 #ifdef USE_WIN32 802 static bool readFullStringValue(HKEY hkey, const char *valueName, 803 std::string &value) { 804 std::wstring WideValueName; 805 if (!llvm::ConvertUTF8toWide(valueName, WideValueName)) 806 return false; 807 808 DWORD result = 0; 809 DWORD valueSize = 0; 810 DWORD type = 0; 811 // First just query for the required size. 812 result = RegQueryValueExW(hkey, WideValueName.c_str(), NULL, &type, NULL, 813 &valueSize); 814 if (result != ERROR_SUCCESS || type != REG_SZ || !valueSize) 815 return false; 816 std::vector<BYTE> buffer(valueSize); 817 result = RegQueryValueExW(hkey, WideValueName.c_str(), NULL, NULL, &buffer[0], 818 &valueSize); 819 if (result == ERROR_SUCCESS) { 820 std::wstring WideValue(reinterpret_cast<const wchar_t *>(buffer.data()), 821 valueSize / sizeof(wchar_t)); 822 if (valueSize && WideValue.back() == L'\0') { 823 WideValue.pop_back(); 824 } 825 // The destination buffer must be empty as an invariant of the conversion 826 // function; but this function is sometimes called in a loop that passes in 827 // the same buffer, however. Simply clear it out so we can overwrite it. 828 value.clear(); 829 return llvm::convertWideToUTF8(WideValue, value); 830 } 831 return false; 832 } 833 #endif 834 835 /// \brief Read registry string. 836 /// This also supports a means to look for high-versioned keys by use 837 /// of a $VERSION placeholder in the key path. 838 /// $VERSION in the key path is a placeholder for the version number, 839 /// causing the highest value path to be searched for and used. 840 /// I.e. "SOFTWARE\\Microsoft\\VisualStudio\\$VERSION". 841 /// There can be additional characters in the component. Only the numeric 842 /// characters are compared. This function only searches HKLM. 843 static bool getSystemRegistryString(const char *keyPath, const char *valueName, 844 std::string &value, std::string *phValue) { 845 #ifndef USE_WIN32 846 return false; 847 #else 848 HKEY hRootKey = HKEY_LOCAL_MACHINE; 849 HKEY hKey = NULL; 850 long lResult; 851 bool returnValue = false; 852 853 const char *placeHolder = strstr(keyPath, "$VERSION"); 854 std::string bestName; 855 // If we have a $VERSION placeholder, do the highest-version search. 856 if (placeHolder) { 857 const char *keyEnd = placeHolder - 1; 858 const char *nextKey = placeHolder; 859 // Find end of previous key. 860 while ((keyEnd > keyPath) && (*keyEnd != '\\')) 861 keyEnd--; 862 // Find end of key containing $VERSION. 863 while (*nextKey && (*nextKey != '\\')) 864 nextKey++; 865 size_t partialKeyLength = keyEnd - keyPath; 866 char partialKey[256]; 867 if (partialKeyLength >= sizeof(partialKey)) 868 partialKeyLength = sizeof(partialKey) - 1; 869 strncpy(partialKey, keyPath, partialKeyLength); 870 partialKey[partialKeyLength] = '\0'; 871 HKEY hTopKey = NULL; 872 lResult = RegOpenKeyExA(hRootKey, partialKey, 0, KEY_READ | KEY_WOW64_32KEY, 873 &hTopKey); 874 if (lResult == ERROR_SUCCESS) { 875 char keyName[256]; 876 double bestValue = 0.0; 877 DWORD index, size = sizeof(keyName) - 1; 878 for (index = 0; RegEnumKeyExA(hTopKey, index, keyName, &size, NULL, NULL, 879 NULL, NULL) == ERROR_SUCCESS; 880 index++) { 881 const char *sp = keyName; 882 while (*sp && !isDigit(*sp)) 883 sp++; 884 if (!*sp) 885 continue; 886 const char *ep = sp + 1; 887 while (*ep && (isDigit(*ep) || (*ep == '.'))) 888 ep++; 889 char numBuf[32]; 890 strncpy(numBuf, sp, sizeof(numBuf) - 1); 891 numBuf[sizeof(numBuf) - 1] = '\0'; 892 double dvalue = strtod(numBuf, NULL); 893 if (dvalue > bestValue) { 894 // Test that InstallDir is indeed there before keeping this index. 895 // Open the chosen key path remainder. 896 bestName = keyName; 897 // Append rest of key. 898 bestName.append(nextKey); 899 lResult = RegOpenKeyExA(hTopKey, bestName.c_str(), 0, 900 KEY_READ | KEY_WOW64_32KEY, &hKey); 901 if (lResult == ERROR_SUCCESS) { 902 if (readFullStringValue(hKey, valueName, value)) { 903 bestValue = dvalue; 904 if (phValue) 905 *phValue = bestName; 906 returnValue = true; 907 } 908 RegCloseKey(hKey); 909 } 910 } 911 size = sizeof(keyName) - 1; 912 } 913 RegCloseKey(hTopKey); 914 } 915 } else { 916 lResult = 917 RegOpenKeyExA(hRootKey, keyPath, 0, KEY_READ | KEY_WOW64_32KEY, &hKey); 918 if (lResult == ERROR_SUCCESS) { 919 if (readFullStringValue(hKey, valueName, value)) 920 returnValue = true; 921 if (phValue) 922 phValue->clear(); 923 RegCloseKey(hKey); 924 } 925 } 926 return returnValue; 927 #endif // USE_WIN32 928 } 929 930 // Find the most recent version of Universal CRT or Windows 10 SDK. 931 // vcvarsqueryregistry.bat from Visual Studio 2015 sorts entries in the include 932 // directory by name and uses the last one of the list. 933 // So we compare entry names lexicographically to find the greatest one. 934 static bool getWindows10SDKVersionFromPath(const std::string &SDKPath, 935 std::string &SDKVersion) { 936 SDKVersion.clear(); 937 938 std::error_code EC; 939 llvm::SmallString<128> IncludePath(SDKPath); 940 llvm::sys::path::append(IncludePath, "Include"); 941 for (llvm::sys::fs::directory_iterator DirIt(IncludePath, EC), DirEnd; 942 DirIt != DirEnd && !EC; DirIt.increment(EC)) { 943 if (!llvm::sys::fs::is_directory(DirIt->path())) 944 continue; 945 StringRef CandidateName = llvm::sys::path::filename(DirIt->path()); 946 // If WDK is installed, there could be subfolders like "wdf" in the 947 // "Include" directory. 948 // Allow only directories which names start with "10.". 949 if (!CandidateName.startswith("10.")) 950 continue; 951 if (CandidateName > SDKVersion) 952 SDKVersion = CandidateName; 953 } 954 955 return !SDKVersion.empty(); 956 } 957 958 /// \brief Get Windows SDK installation directory. 959 static bool getWindowsSDKDir(std::string &Path, int &Major, 960 std::string &WindowsSDKIncludeVersion, 961 std::string &WindowsSDKLibVersion) { 962 std::string RegistrySDKVersion; 963 // Try the Windows registry. 964 if (!getSystemRegistryString( 965 "SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\$VERSION", 966 "InstallationFolder", Path, &RegistrySDKVersion)) 967 return false; 968 if (Path.empty() || RegistrySDKVersion.empty()) 969 return false; 970 971 WindowsSDKIncludeVersion.clear(); 972 WindowsSDKLibVersion.clear(); 973 Major = 0; 974 std::sscanf(RegistrySDKVersion.c_str(), "v%d.", &Major); 975 if (Major <= 7) 976 return true; 977 if (Major == 8) { 978 // Windows SDK 8.x installs libraries in a folder whose names depend on the 979 // version of the OS you're targeting. By default choose the newest, which 980 // usually corresponds to the version of the OS you've installed the SDK on. 981 const char *Tests[] = {"winv6.3", "win8", "win7"}; 982 for (const char *Test : Tests) { 983 llvm::SmallString<128> TestPath(Path); 984 llvm::sys::path::append(TestPath, "Lib", Test); 985 if (llvm::sys::fs::exists(TestPath.c_str())) { 986 WindowsSDKLibVersion = Test; 987 break; 988 } 989 } 990 return !WindowsSDKLibVersion.empty(); 991 } 992 if (Major == 10) { 993 if (!getWindows10SDKVersionFromPath(Path, WindowsSDKIncludeVersion)) 994 return false; 995 WindowsSDKLibVersion = WindowsSDKIncludeVersion; 996 return true; 997 } 998 // Unsupported SDK version 999 return false; 1000 } 1001 1002 // Gets the library path required to link against the Windows SDK. 1003 bool MSVCToolChain::getWindowsSDKLibraryPath(std::string &path) const { 1004 std::string sdkPath; 1005 int sdkMajor = 0; 1006 std::string windowsSDKIncludeVersion; 1007 std::string windowsSDKLibVersion; 1008 1009 path.clear(); 1010 if (!getWindowsSDKDir(sdkPath, sdkMajor, windowsSDKIncludeVersion, 1011 windowsSDKLibVersion)) 1012 return false; 1013 1014 llvm::SmallString<128> libPath(sdkPath); 1015 llvm::sys::path::append(libPath, "Lib"); 1016 if (sdkMajor >= 8) { 1017 llvm::sys::path::append(libPath, windowsSDKLibVersion, "um", 1018 llvmArchToWindowsSDKArch(getArch())); 1019 } else { 1020 switch (getArch()) { 1021 // In Windows SDK 7.x, x86 libraries are directly in the Lib folder. 1022 case llvm::Triple::x86: 1023 break; 1024 case llvm::Triple::x86_64: 1025 llvm::sys::path::append(libPath, "x64"); 1026 break; 1027 case llvm::Triple::arm: 1028 // It is not necessary to link against Windows SDK 7.x when targeting ARM. 1029 return false; 1030 default: 1031 return false; 1032 } 1033 } 1034 1035 path = libPath.str(); 1036 return true; 1037 } 1038 1039 // Check if the Include path of a specified version of Visual Studio contains 1040 // specific header files. If not, they are probably shipped with Universal CRT. 1041 bool MSVCToolChain::useUniversalCRT() const { 1042 llvm::SmallString<128> TestPath( 1043 getSubDirectoryPath(SubDirectoryType::Include)); 1044 llvm::sys::path::append(TestPath, "stdlib.h"); 1045 return !llvm::sys::fs::exists(TestPath); 1046 } 1047 1048 static bool getUniversalCRTSdkDir(std::string &Path, std::string &UCRTVersion) { 1049 // vcvarsqueryregistry.bat for Visual Studio 2015 queries the registry 1050 // for the specific key "KitsRoot10". So do we. 1051 if (!getSystemRegistryString( 1052 "SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots", "KitsRoot10", 1053 Path, nullptr)) 1054 return false; 1055 1056 return getWindows10SDKVersionFromPath(Path, UCRTVersion); 1057 } 1058 1059 bool MSVCToolChain::getUniversalCRTLibraryPath(std::string &Path) const { 1060 std::string UniversalCRTSdkPath; 1061 std::string UCRTVersion; 1062 1063 Path.clear(); 1064 if (!getUniversalCRTSdkDir(UniversalCRTSdkPath, UCRTVersion)) 1065 return false; 1066 1067 StringRef ArchName = llvmArchToWindowsSDKArch(getArch()); 1068 if (ArchName.empty()) 1069 return false; 1070 1071 llvm::SmallString<128> LibPath(UniversalCRTSdkPath); 1072 llvm::sys::path::append(LibPath, "Lib", UCRTVersion, "ucrt", ArchName); 1073 1074 Path = LibPath.str(); 1075 return true; 1076 } 1077 1078 static VersionTuple getMSVCVersionFromTriple(const llvm::Triple &Triple) { 1079 unsigned Major, Minor, Micro; 1080 Triple.getEnvironmentVersion(Major, Minor, Micro); 1081 if (Major || Minor || Micro) 1082 return VersionTuple(Major, Minor, Micro); 1083 return VersionTuple(); 1084 } 1085 1086 static VersionTuple getMSVCVersionFromExe(const std::string &BinDir) { 1087 VersionTuple Version; 1088 #ifdef USE_WIN32 1089 SmallString<128> ClExe(BinDir); 1090 llvm::sys::path::append(ClExe, "cl.exe"); 1091 1092 std::wstring ClExeWide; 1093 if (!llvm::ConvertUTF8toWide(ClExe.c_str(), ClExeWide)) 1094 return Version; 1095 1096 const DWORD VersionSize = ::GetFileVersionInfoSizeW(ClExeWide.c_str(), 1097 nullptr); 1098 if (VersionSize == 0) 1099 return Version; 1100 1101 SmallVector<uint8_t, 4 * 1024> VersionBlock(VersionSize); 1102 if (!::GetFileVersionInfoW(ClExeWide.c_str(), 0, VersionSize, 1103 VersionBlock.data())) 1104 return Version; 1105 1106 VS_FIXEDFILEINFO *FileInfo = nullptr; 1107 UINT FileInfoSize = 0; 1108 if (!::VerQueryValueW(VersionBlock.data(), L"\\", 1109 reinterpret_cast<LPVOID *>(&FileInfo), &FileInfoSize) || 1110 FileInfoSize < sizeof(*FileInfo)) 1111 return Version; 1112 1113 const unsigned Major = (FileInfo->dwFileVersionMS >> 16) & 0xFFFF; 1114 const unsigned Minor = (FileInfo->dwFileVersionMS ) & 0xFFFF; 1115 const unsigned Micro = (FileInfo->dwFileVersionLS >> 16) & 0xFFFF; 1116 1117 Version = VersionTuple(Major, Minor, Micro); 1118 #endif 1119 return Version; 1120 } 1121 1122 void MSVCToolChain::AddSystemIncludeWithSubfolder( 1123 const ArgList &DriverArgs, ArgStringList &CC1Args, 1124 const std::string &folder, const Twine &subfolder1, const Twine &subfolder2, 1125 const Twine &subfolder3) const { 1126 llvm::SmallString<128> path(folder); 1127 llvm::sys::path::append(path, subfolder1, subfolder2, subfolder3); 1128 addSystemInclude(DriverArgs, CC1Args, path); 1129 } 1130 1131 void MSVCToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs, 1132 ArgStringList &CC1Args) const { 1133 if (DriverArgs.hasArg(options::OPT_nostdinc)) 1134 return; 1135 1136 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) { 1137 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, getDriver().ResourceDir, 1138 "include"); 1139 } 1140 1141 // Add %INCLUDE%-like directories from the -imsvc flag. 1142 for (const auto &Path : DriverArgs.getAllArgValues(options::OPT__SLASH_imsvc)) 1143 addSystemInclude(DriverArgs, CC1Args, Path); 1144 1145 if (DriverArgs.hasArg(options::OPT_nostdlibinc)) 1146 return; 1147 1148 // Honor %INCLUDE%. It should know essential search paths with vcvarsall.bat. 1149 if (llvm::Optional<std::string> cl_include_dir = 1150 llvm::sys::Process::GetEnv("INCLUDE")) { 1151 SmallVector<StringRef, 8> Dirs; 1152 StringRef(*cl_include_dir) 1153 .split(Dirs, ";", /*MaxSplit=*/-1, /*KeepEmpty=*/false); 1154 for (StringRef Dir : Dirs) 1155 addSystemInclude(DriverArgs, CC1Args, Dir); 1156 if (!Dirs.empty()) 1157 return; 1158 } 1159 1160 // When built with access to the proper Windows APIs, try to actually find 1161 // the correct include paths first. 1162 if (!VCToolChainPath.empty()) { 1163 addSystemInclude(DriverArgs, CC1Args, 1164 getSubDirectoryPath(SubDirectoryType::Include)); 1165 1166 if (useUniversalCRT()) { 1167 std::string UniversalCRTSdkPath; 1168 std::string UCRTVersion; 1169 if (getUniversalCRTSdkDir(UniversalCRTSdkPath, UCRTVersion)) { 1170 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, UniversalCRTSdkPath, 1171 "Include", UCRTVersion, "ucrt"); 1172 } 1173 } 1174 1175 std::string WindowsSDKDir; 1176 int major; 1177 std::string windowsSDKIncludeVersion; 1178 std::string windowsSDKLibVersion; 1179 if (getWindowsSDKDir(WindowsSDKDir, major, windowsSDKIncludeVersion, 1180 windowsSDKLibVersion)) { 1181 if (major >= 8) { 1182 // Note: windowsSDKIncludeVersion is empty for SDKs prior to v10. 1183 // Anyway, llvm::sys::path::append is able to manage it. 1184 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir, 1185 "include", windowsSDKIncludeVersion, 1186 "shared"); 1187 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir, 1188 "include", windowsSDKIncludeVersion, 1189 "um"); 1190 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir, 1191 "include", windowsSDKIncludeVersion, 1192 "winrt"); 1193 } else { 1194 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir, 1195 "include"); 1196 } 1197 } 1198 1199 return; 1200 } 1201 1202 #if defined(LLVM_ON_WIN32) 1203 // As a fallback, select default install paths. 1204 // FIXME: Don't guess drives and paths like this on Windows. 1205 const StringRef Paths[] = { 1206 "C:/Program Files/Microsoft Visual Studio 10.0/VC/include", 1207 "C:/Program Files/Microsoft Visual Studio 9.0/VC/include", 1208 "C:/Program Files/Microsoft Visual Studio 9.0/VC/PlatformSDK/Include", 1209 "C:/Program Files/Microsoft Visual Studio 8/VC/include", 1210 "C:/Program Files/Microsoft Visual Studio 8/VC/PlatformSDK/Include" 1211 }; 1212 addSystemIncludes(DriverArgs, CC1Args, Paths); 1213 #endif 1214 } 1215 1216 void MSVCToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, 1217 ArgStringList &CC1Args) const { 1218 // FIXME: There should probably be logic here to find libc++ on Windows. 1219 } 1220 1221 VersionTuple MSVCToolChain::computeMSVCVersion(const Driver *D, 1222 const ArgList &Args) const { 1223 bool IsWindowsMSVC = getTriple().isWindowsMSVCEnvironment(); 1224 VersionTuple MSVT = ToolChain::computeMSVCVersion(D, Args); 1225 if (MSVT.empty()) 1226 MSVT = getMSVCVersionFromTriple(getTriple()); 1227 if (MSVT.empty() && IsWindowsMSVC) 1228 MSVT = getMSVCVersionFromExe(getSubDirectoryPath(SubDirectoryType::Bin)); 1229 if (MSVT.empty() && 1230 Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions, 1231 IsWindowsMSVC)) { 1232 // -fms-compatibility-version=18.00 is default. 1233 // FIXME: Consider bumping this to 19 (MSVC2015) soon. 1234 MSVT = VersionTuple(18); 1235 } 1236 return MSVT; 1237 } 1238 1239 std::string 1240 MSVCToolChain::ComputeEffectiveClangTriple(const ArgList &Args, 1241 types::ID InputType) const { 1242 // The MSVC version doesn't care about the architecture, even though it 1243 // may look at the triple internally. 1244 VersionTuple MSVT = computeMSVCVersion(/*D=*/nullptr, Args); 1245 MSVT = VersionTuple(MSVT.getMajor(), MSVT.getMinor().getValueOr(0), 1246 MSVT.getSubminor().getValueOr(0)); 1247 1248 // For the rest of the triple, however, a computed architecture name may 1249 // be needed. 1250 llvm::Triple Triple(ToolChain::ComputeEffectiveClangTriple(Args, InputType)); 1251 if (Triple.getEnvironment() == llvm::Triple::MSVC) { 1252 StringRef ObjFmt = Triple.getEnvironmentName().split('-').second; 1253 if (ObjFmt.empty()) 1254 Triple.setEnvironmentName((Twine("msvc") + MSVT.getAsString()).str()); 1255 else 1256 Triple.setEnvironmentName( 1257 (Twine("msvc") + MSVT.getAsString() + Twine('-') + ObjFmt).str()); 1258 } 1259 return Triple.getTriple(); 1260 } 1261 1262 SanitizerMask MSVCToolChain::getSupportedSanitizers() const { 1263 SanitizerMask Res = ToolChain::getSupportedSanitizers(); 1264 Res |= SanitizerKind::Address; 1265 return Res; 1266 } 1267 1268 static void TranslateOptArg(Arg *A, llvm::opt::DerivedArgList &DAL, 1269 bool SupportsForcingFramePointer, 1270 const char *ExpandChar, const OptTable &Opts) { 1271 assert(A->getOption().matches(options::OPT__SLASH_O)); 1272 1273 StringRef OptStr = A->getValue(); 1274 for (size_t I = 0, E = OptStr.size(); I != E; ++I) { 1275 const char &OptChar = *(OptStr.data() + I); 1276 switch (OptChar) { 1277 default: 1278 break; 1279 case '1': 1280 case '2': 1281 case 'x': 1282 case 'd': 1283 if (&OptChar == ExpandChar) { 1284 if (OptChar == 'd') { 1285 DAL.AddFlagArg(A, Opts.getOption(options::OPT_O0)); 1286 } else { 1287 if (OptChar == '1') { 1288 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "s"); 1289 } else if (OptChar == '2' || OptChar == 'x') { 1290 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin)); 1291 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "2"); 1292 } 1293 if (SupportsForcingFramePointer && 1294 !DAL.hasArgNoClaim(options::OPT_fno_omit_frame_pointer)) 1295 DAL.AddFlagArg(A, 1296 Opts.getOption(options::OPT_fomit_frame_pointer)); 1297 if (OptChar == '1' || OptChar == '2') 1298 DAL.AddFlagArg(A, 1299 Opts.getOption(options::OPT_ffunction_sections)); 1300 } 1301 } 1302 break; 1303 case 'b': 1304 if (I + 1 != E && isdigit(OptStr[I + 1])) { 1305 switch (OptStr[I + 1]) { 1306 case '0': 1307 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_inline)); 1308 break; 1309 case '1': 1310 DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_hint_functions)); 1311 break; 1312 case '2': 1313 DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_functions)); 1314 break; 1315 } 1316 ++I; 1317 } 1318 break; 1319 case 'g': 1320 break; 1321 case 'i': 1322 if (I + 1 != E && OptStr[I + 1] == '-') { 1323 ++I; 1324 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_builtin)); 1325 } else { 1326 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin)); 1327 } 1328 break; 1329 case 's': 1330 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "s"); 1331 break; 1332 case 't': 1333 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "2"); 1334 break; 1335 case 'y': { 1336 bool OmitFramePointer = true; 1337 if (I + 1 != E && OptStr[I + 1] == '-') { 1338 OmitFramePointer = false; 1339 ++I; 1340 } 1341 if (SupportsForcingFramePointer) { 1342 if (OmitFramePointer) 1343 DAL.AddFlagArg(A, 1344 Opts.getOption(options::OPT_fomit_frame_pointer)); 1345 else 1346 DAL.AddFlagArg( 1347 A, Opts.getOption(options::OPT_fno_omit_frame_pointer)); 1348 } else { 1349 // Don't warn about /Oy- in 64-bit builds (where 1350 // SupportsForcingFramePointer is false). The flag having no effect 1351 // there is a compiler-internal optimization, and people shouldn't have 1352 // to special-case their build files for 64-bit clang-cl. 1353 A->claim(); 1354 } 1355 break; 1356 } 1357 } 1358 } 1359 } 1360 1361 static void TranslateDArg(Arg *A, llvm::opt::DerivedArgList &DAL, 1362 const OptTable &Opts) { 1363 assert(A->getOption().matches(options::OPT_D)); 1364 1365 StringRef Val = A->getValue(); 1366 size_t Hash = Val.find('#'); 1367 if (Hash == StringRef::npos || Hash > Val.find('=')) { 1368 DAL.append(A); 1369 return; 1370 } 1371 1372 std::string NewVal = Val; 1373 NewVal[Hash] = '='; 1374 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_D), NewVal); 1375 } 1376 1377 llvm::opt::DerivedArgList * 1378 MSVCToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args, 1379 StringRef BoundArch, Action::OffloadKind) const { 1380 DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs()); 1381 const OptTable &Opts = getDriver().getOpts(); 1382 1383 // /Oy and /Oy- only has an effect under X86-32. 1384 bool SupportsForcingFramePointer = getArch() == llvm::Triple::x86; 1385 1386 // The -O[12xd] flag actually expands to several flags. We must desugar the 1387 // flags so that options embedded can be negated. For example, the '-O2' flag 1388 // enables '-Oy'. Expanding '-O2' into its constituent flags allows us to 1389 // correctly handle '-O2 -Oy-' where the trailing '-Oy-' disables a single 1390 // aspect of '-O2'. 1391 // 1392 // Note that this expansion logic only applies to the *last* of '[12xd]'. 1393 1394 // First step is to search for the character we'd like to expand. 1395 const char *ExpandChar = nullptr; 1396 for (Arg *A : Args) { 1397 if (!A->getOption().matches(options::OPT__SLASH_O)) 1398 continue; 1399 StringRef OptStr = A->getValue(); 1400 for (size_t I = 0, E = OptStr.size(); I != E; ++I) { 1401 char OptChar = OptStr[I]; 1402 char PrevChar = I > 0 ? OptStr[I - 1] : '0'; 1403 if (PrevChar == 'b') { 1404 // OptChar does not expand; it's an argument to the previous char. 1405 continue; 1406 } 1407 if (OptChar == '1' || OptChar == '2' || OptChar == 'x' || OptChar == 'd') 1408 ExpandChar = OptStr.data() + I; 1409 } 1410 } 1411 1412 for (Arg *A : Args) { 1413 if (A->getOption().matches(options::OPT__SLASH_O)) { 1414 // The -O flag actually takes an amalgam of other options. For example, 1415 // '/Ogyb2' is equivalent to '/Og' '/Oy' '/Ob2'. 1416 TranslateOptArg(A, *DAL, SupportsForcingFramePointer, ExpandChar, Opts); 1417 } else if (A->getOption().matches(options::OPT_D)) { 1418 // Translate -Dfoo#bar into -Dfoo=bar. 1419 TranslateDArg(A, *DAL, Opts); 1420 } else { 1421 DAL->append(A); 1422 } 1423 } 1424 1425 return DAL; 1426 } 1427