1 //===--- ToolChains.cpp - ToolChain Implementations -----------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "ToolChains.h"
12 #include "clang/Basic/CharInfo.h"
13 #include "clang/Basic/Version.h"
14 #include "clang/Driver/Compilation.h"
15 #include "clang/Driver/Driver.h"
16 #include "clang/Driver/DriverDiagnostic.h"
17 #include "clang/Driver/Options.h"
18 #include "llvm/ADT/StringExtras.h"
19 #include "llvm/ADT/StringSwitch.h"
20 #include "llvm/Config/llvm-config.h"
21 #include "llvm/Option/Arg.h"
22 #include "llvm/Option/ArgList.h"
23 #include "llvm/Support/ConvertUTF.h"
24 #include "llvm/Support/ErrorHandling.h"
25 #include "llvm/Support/FileSystem.h"
26 #include "llvm/Support/Path.h"
27 #include "llvm/Support/Process.h"
30 // Include the necessary headers to interface with the Windows registry and
32 #if defined(LLVM_ON_WIN32)
37 #define WIN32_LEAN_AND_MEAN
45 using namespace clang::driver;
46 using namespace clang::driver::toolchains;
47 using namespace clang;
48 using namespace llvm::opt;
50 MSVCToolChain::MSVCToolChain(const Driver &D, const llvm::Triple &Triple,
52 : ToolChain(D, Triple, Args), CudaInstallation(D, Triple, Args) {
53 getProgramPaths().push_back(getDriver().getInstalledDir());
54 if (getDriver().getInstalledDir() != getDriver().Dir)
55 getProgramPaths().push_back(getDriver().Dir);
58 Tool *MSVCToolChain::buildLinker() const {
59 return new tools::visualstudio::Linker(*this);
62 Tool *MSVCToolChain::buildAssembler() const {
63 if (getTriple().isOSBinFormatMachO())
64 return new tools::darwin::Assembler(*this);
65 getDriver().Diag(clang::diag::err_no_external_assembler);
69 bool MSVCToolChain::IsIntegratedAssemblerDefault() const {
73 bool MSVCToolChain::IsUnwindTablesDefault() const {
74 // Emit unwind tables by default on Win64. All non-x86_32 Windows platforms
75 // such as ARM and PPC actually require unwind tables, but LLVM doesn't know
76 // how to generate them yet.
78 // Don't emit unwind tables by default for MachO targets.
79 if (getTriple().isOSBinFormatMachO())
82 return getArch() == llvm::Triple::x86_64;
85 bool MSVCToolChain::isPICDefault() const {
86 return getArch() == llvm::Triple::x86_64;
89 bool MSVCToolChain::isPIEDefault() const {
93 bool MSVCToolChain::isPICDefaultForced() const {
94 return getArch() == llvm::Triple::x86_64;
97 void MSVCToolChain::AddCudaIncludeArgs(const ArgList &DriverArgs,
98 ArgStringList &CC1Args) const {
99 CudaInstallation.AddCudaIncludeArgs(DriverArgs, CC1Args);
102 void MSVCToolChain::printVerboseInfo(raw_ostream &OS) const {
103 CudaInstallation.print(OS);
107 static bool readFullStringValue(HKEY hkey, const char *valueName,
108 std::string &value) {
109 std::wstring WideValueName;
110 if (!llvm::ConvertUTF8toWide(valueName, WideValueName))
116 // First just query for the required size.
117 result = RegQueryValueExW(hkey, WideValueName.c_str(), NULL, &type, NULL,
119 if (result != ERROR_SUCCESS || type != REG_SZ || !valueSize)
121 std::vector<BYTE> buffer(valueSize);
122 result = RegQueryValueExW(hkey, WideValueName.c_str(), NULL, NULL, &buffer[0],
124 if (result == ERROR_SUCCESS) {
125 std::wstring WideValue(reinterpret_cast<const wchar_t *>(buffer.data()),
126 valueSize / sizeof(wchar_t));
127 if (valueSize && WideValue.back() == L'\0') {
128 WideValue.pop_back();
130 // The destination buffer must be empty as an invariant of the conversion
131 // function; but this function is sometimes called in a loop that passes in
132 // the same buffer, however. Simply clear it out so we can overwrite it.
134 return llvm::convertWideToUTF8(WideValue, value);
140 /// \brief Read registry string.
141 /// This also supports a means to look for high-versioned keys by use
142 /// of a $VERSION placeholder in the key path.
143 /// $VERSION in the key path is a placeholder for the version number,
144 /// causing the highest value path to be searched for and used.
145 /// I.e. "SOFTWARE\\Microsoft\\VisualStudio\\$VERSION".
146 /// There can be additional characters in the component. Only the numeric
147 /// characters are compared. This function only searches HKLM.
148 static bool getSystemRegistryString(const char *keyPath, const char *valueName,
149 std::string &value, std::string *phValue) {
153 HKEY hRootKey = HKEY_LOCAL_MACHINE;
156 bool returnValue = false;
158 const char *placeHolder = strstr(keyPath, "$VERSION");
159 std::string bestName;
160 // If we have a $VERSION placeholder, do the highest-version search.
162 const char *keyEnd = placeHolder - 1;
163 const char *nextKey = placeHolder;
164 // Find end of previous key.
165 while ((keyEnd > keyPath) && (*keyEnd != '\\'))
167 // Find end of key containing $VERSION.
168 while (*nextKey && (*nextKey != '\\'))
170 size_t partialKeyLength = keyEnd - keyPath;
171 char partialKey[256];
172 if (partialKeyLength >= sizeof(partialKey))
173 partialKeyLength = sizeof(partialKey) - 1;
174 strncpy(partialKey, keyPath, partialKeyLength);
175 partialKey[partialKeyLength] = '\0';
177 lResult = RegOpenKeyExA(hRootKey, partialKey, 0, KEY_READ | KEY_WOW64_32KEY,
179 if (lResult == ERROR_SUCCESS) {
181 double bestValue = 0.0;
182 DWORD index, size = sizeof(keyName) - 1;
183 for (index = 0; RegEnumKeyExA(hTopKey, index, keyName, &size, NULL, NULL,
184 NULL, NULL) == ERROR_SUCCESS;
186 const char *sp = keyName;
187 while (*sp && !isDigit(*sp))
191 const char *ep = sp + 1;
192 while (*ep && (isDigit(*ep) || (*ep == '.')))
195 strncpy(numBuf, sp, sizeof(numBuf) - 1);
196 numBuf[sizeof(numBuf) - 1] = '\0';
197 double dvalue = strtod(numBuf, NULL);
198 if (dvalue > bestValue) {
199 // Test that InstallDir is indeed there before keeping this index.
200 // Open the chosen key path remainder.
202 // Append rest of key.
203 bestName.append(nextKey);
204 lResult = RegOpenKeyExA(hTopKey, bestName.c_str(), 0,
205 KEY_READ | KEY_WOW64_32KEY, &hKey);
206 if (lResult == ERROR_SUCCESS) {
207 if (readFullStringValue(hKey, valueName, value)) {
216 size = sizeof(keyName) - 1;
218 RegCloseKey(hTopKey);
222 RegOpenKeyExA(hRootKey, keyPath, 0, KEY_READ | KEY_WOW64_32KEY, &hKey);
223 if (lResult == ERROR_SUCCESS) {
224 if (readFullStringValue(hKey, valueName, value))
235 // Convert LLVM's ArchType
236 // to the corresponding name of Windows SDK libraries subfolder
237 static StringRef getWindowsSDKArch(llvm::Triple::ArchType Arch) {
239 case llvm::Triple::x86:
241 case llvm::Triple::x86_64:
243 case llvm::Triple::arm:
250 // Find the most recent version of Universal CRT or Windows 10 SDK.
251 // vcvarsqueryregistry.bat from Visual Studio 2015 sorts entries in the include
252 // directory by name and uses the last one of the list.
253 // So we compare entry names lexicographically to find the greatest one.
254 static bool getWindows10SDKVersion(const std::string &SDKPath,
255 std::string &SDKVersion) {
259 llvm::SmallString<128> IncludePath(SDKPath);
260 llvm::sys::path::append(IncludePath, "Include");
261 for (llvm::sys::fs::directory_iterator DirIt(IncludePath, EC), DirEnd;
262 DirIt != DirEnd && !EC; DirIt.increment(EC)) {
263 if (!llvm::sys::fs::is_directory(DirIt->path()))
265 StringRef CandidateName = llvm::sys::path::filename(DirIt->path());
266 // If WDK is installed, there could be subfolders like "wdf" in the
267 // "Include" directory.
268 // Allow only directories which names start with "10.".
269 if (!CandidateName.startswith("10."))
271 if (CandidateName > SDKVersion)
272 SDKVersion = CandidateName;
275 return !SDKVersion.empty();
278 /// \brief Get Windows SDK installation directory.
279 bool MSVCToolChain::getWindowsSDKDir(std::string &Path, int &Major,
280 std::string &WindowsSDKIncludeVersion,
281 std::string &WindowsSDKLibVersion) const {
282 std::string RegistrySDKVersion;
283 // Try the Windows registry.
284 if (!getSystemRegistryString(
285 "SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\$VERSION",
286 "InstallationFolder", Path, &RegistrySDKVersion))
288 if (Path.empty() || RegistrySDKVersion.empty())
291 WindowsSDKIncludeVersion.clear();
292 WindowsSDKLibVersion.clear();
294 std::sscanf(RegistrySDKVersion.c_str(), "v%d.", &Major);
298 // Windows SDK 8.x installs libraries in a folder whose names depend on the
299 // version of the OS you're targeting. By default choose the newest, which
300 // usually corresponds to the version of the OS you've installed the SDK on.
301 const char *Tests[] = {"winv6.3", "win8", "win7"};
302 for (const char *Test : Tests) {
303 llvm::SmallString<128> TestPath(Path);
304 llvm::sys::path::append(TestPath, "Lib", Test);
305 if (llvm::sys::fs::exists(TestPath.c_str())) {
306 WindowsSDKLibVersion = Test;
310 return !WindowsSDKLibVersion.empty();
313 if (!getWindows10SDKVersion(Path, WindowsSDKIncludeVersion))
315 WindowsSDKLibVersion = WindowsSDKIncludeVersion;
318 // Unsupported SDK version
322 // Gets the library path required to link against the Windows SDK.
323 bool MSVCToolChain::getWindowsSDKLibraryPath(std::string &path) const {
326 std::string windowsSDKIncludeVersion;
327 std::string windowsSDKLibVersion;
330 if (!getWindowsSDKDir(sdkPath, sdkMajor, windowsSDKIncludeVersion,
331 windowsSDKLibVersion))
334 llvm::SmallString<128> libPath(sdkPath);
335 llvm::sys::path::append(libPath, "Lib");
338 // In Windows SDK 7.x, x86 libraries are directly in the Lib folder.
339 case llvm::Triple::x86:
341 case llvm::Triple::x86_64:
342 llvm::sys::path::append(libPath, "x64");
344 case llvm::Triple::arm:
345 // It is not necessary to link against Windows SDK 7.x when targeting ARM.
351 const StringRef archName = getWindowsSDKArch(getArch());
352 if (archName.empty())
354 llvm::sys::path::append(libPath, windowsSDKLibVersion, "um", archName);
357 path = libPath.str();
361 // Check if the Include path of a specified version of Visual Studio contains
362 // specific header files. If not, they are probably shipped with Universal CRT.
363 bool clang::driver::toolchains::MSVCToolChain::useUniversalCRT(
364 std::string &VisualStudioDir) const {
365 llvm::SmallString<128> TestPath(VisualStudioDir);
366 llvm::sys::path::append(TestPath, "VC\\include\\stdlib.h");
368 return !llvm::sys::fs::exists(TestPath);
371 bool MSVCToolChain::getUniversalCRTSdkDir(std::string &Path,
372 std::string &UCRTVersion) const {
373 // vcvarsqueryregistry.bat for Visual Studio 2015 queries the registry
374 // for the specific key "KitsRoot10". So do we.
375 if (!getSystemRegistryString(
376 "SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots", "KitsRoot10",
380 return getWindows10SDKVersion(Path, UCRTVersion);
383 bool MSVCToolChain::getUniversalCRTLibraryPath(std::string &Path) const {
384 std::string UniversalCRTSdkPath;
385 std::string UCRTVersion;
388 if (!getUniversalCRTSdkDir(UniversalCRTSdkPath, UCRTVersion))
391 StringRef ArchName = getWindowsSDKArch(getArch());
392 if (ArchName.empty())
395 llvm::SmallString<128> LibPath(UniversalCRTSdkPath);
396 llvm::sys::path::append(LibPath, "Lib", UCRTVersion, "ucrt", ArchName);
398 Path = LibPath.str();
402 // Get the location to use for Visual Studio binaries. The location priority
403 // is: %VCINSTALLDIR% > %PATH% > newest copy of Visual Studio installed on
404 // system (as reported by the registry).
405 bool MSVCToolChain::getVisualStudioBinariesFolder(const char *clangProgramPath,
406 std::string &path) const {
409 SmallString<128> BinDir;
411 // First check the environment variables that vsvars32.bat sets.
412 llvm::Optional<std::string> VcInstallDir =
413 llvm::sys::Process::GetEnv("VCINSTALLDIR");
414 if (VcInstallDir.hasValue()) {
415 BinDir = VcInstallDir.getValue();
416 llvm::sys::path::append(BinDir, "bin");
418 // Next walk the PATH, trying to find a cl.exe in the path. If we find one,
419 // use that. However, make sure it's not clang's cl.exe.
420 llvm::Optional<std::string> OptPath = llvm::sys::Process::GetEnv("PATH");
421 if (OptPath.hasValue()) {
422 const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'};
423 SmallVector<StringRef, 8> PathSegments;
424 llvm::SplitString(OptPath.getValue(), PathSegments, EnvPathSeparatorStr);
426 for (StringRef PathSegment : PathSegments) {
427 if (PathSegment.empty())
430 SmallString<128> FilePath(PathSegment);
431 llvm::sys::path::append(FilePath, "cl.exe");
432 // Checking if cl.exe exists is a small optimization over calling
433 // can_execute, which really only checks for existence but will also do
434 // extra checks for cl.exe.exe. These add up when walking a long path.
435 if (llvm::sys::fs::exists(FilePath.c_str()) &&
436 !llvm::sys::fs::equivalent(FilePath.c_str(), clangProgramPath)) {
437 // If we found it on the PATH, use it exactly as is with no
445 std::string installDir;
446 // With no VCINSTALLDIR and nothing on the PATH, if we can't find it in the
447 // registry then we have no choice but to fail.
448 if (!getVisualStudioInstallDir(installDir))
451 // Regardless of what binary we're ultimately trying to find, we make sure
452 // that this is a Visual Studio directory by checking for cl.exe. We use
453 // cl.exe instead of other binaries like link.exe because programs such as
454 // GnuWin32 also have a utility called link.exe, so cl.exe is the least
457 llvm::sys::path::append(BinDir, "VC", "bin");
458 SmallString<128> ClPath(BinDir);
459 llvm::sys::path::append(ClPath, "cl.exe");
461 if (!llvm::sys::fs::can_execute(ClPath.c_str()))
469 case llvm::Triple::x86:
471 case llvm::Triple::x86_64:
472 llvm::sys::path::append(BinDir, "amd64");
474 case llvm::Triple::arm:
475 llvm::sys::path::append(BinDir, "arm");
478 // Whatever this is, Visual Studio doesn't have a toolchain for it.
485 VersionTuple MSVCToolChain::getMSVCVersionFromTriple() const {
486 unsigned Major, Minor, Micro;
487 getTriple().getEnvironmentVersion(Major, Minor, Micro);
488 if (Major || Minor || Micro)
489 return VersionTuple(Major, Minor, Micro);
490 return VersionTuple();
493 VersionTuple MSVCToolChain::getMSVCVersionFromExe() const {
494 VersionTuple Version;
497 if (!getVisualStudioBinariesFolder("", BinPath))
499 SmallString<128> ClExe(BinPath);
500 llvm::sys::path::append(ClExe, "cl.exe");
502 std::wstring ClExeWide;
503 if (!llvm::ConvertUTF8toWide(ClExe.c_str(), ClExeWide))
506 const DWORD VersionSize = ::GetFileVersionInfoSizeW(ClExeWide.c_str(),
508 if (VersionSize == 0)
511 SmallVector<uint8_t, 4 * 1024> VersionBlock(VersionSize);
512 if (!::GetFileVersionInfoW(ClExeWide.c_str(), 0, VersionSize,
513 VersionBlock.data()))
516 VS_FIXEDFILEINFO *FileInfo = nullptr;
517 UINT FileInfoSize = 0;
518 if (!::VerQueryValueW(VersionBlock.data(), L"\\",
519 reinterpret_cast<LPVOID *>(&FileInfo), &FileInfoSize) ||
520 FileInfoSize < sizeof(*FileInfo))
523 const unsigned Major = (FileInfo->dwFileVersionMS >> 16) & 0xFFFF;
524 const unsigned Minor = (FileInfo->dwFileVersionMS ) & 0xFFFF;
525 const unsigned Micro = (FileInfo->dwFileVersionLS >> 16) & 0xFFFF;
527 Version = VersionTuple(Major, Minor, Micro);
532 // Get Visual Studio installation directory.
533 bool MSVCToolChain::getVisualStudioInstallDir(std::string &path) const {
534 // First check the environment variables that vsvars32.bat sets.
535 if (llvm::Optional<std::string> VcInstallDir =
536 llvm::sys::Process::GetEnv("VCINSTALLDIR")) {
537 path = std::move(*VcInstallDir);
538 path = path.substr(0, path.find("\\VC"));
542 std::string vsIDEInstallDir;
543 std::string vsExpressIDEInstallDir;
544 // Then try the windows registry.
546 getSystemRegistryString("SOFTWARE\\Microsoft\\VisualStudio\\$VERSION",
547 "InstallDir", vsIDEInstallDir, nullptr);
548 if (hasVCDir && !vsIDEInstallDir.empty()) {
549 path = vsIDEInstallDir.substr(0, vsIDEInstallDir.find("\\Common7\\IDE"));
553 bool hasVCExpressDir =
554 getSystemRegistryString("SOFTWARE\\Microsoft\\VCExpress\\$VERSION",
555 "InstallDir", vsExpressIDEInstallDir, nullptr);
556 if (hasVCExpressDir && !vsExpressIDEInstallDir.empty()) {
557 path = vsExpressIDEInstallDir.substr(
558 0, vsIDEInstallDir.find("\\Common7\\IDE"));
562 // Try the environment.
563 std::string vcomntools;
564 if (llvm::Optional<std::string> vs120comntools =
565 llvm::sys::Process::GetEnv("VS120COMNTOOLS"))
566 vcomntools = std::move(*vs120comntools);
567 else if (llvm::Optional<std::string> vs100comntools =
568 llvm::sys::Process::GetEnv("VS100COMNTOOLS"))
569 vcomntools = std::move(*vs100comntools);
570 else if (llvm::Optional<std::string> vs90comntools =
571 llvm::sys::Process::GetEnv("VS90COMNTOOLS"))
572 vcomntools = std::move(*vs90comntools);
573 else if (llvm::Optional<std::string> vs80comntools =
574 llvm::sys::Process::GetEnv("VS80COMNTOOLS"))
575 vcomntools = std::move(*vs80comntools);
577 // Find any version we can.
578 if (!vcomntools.empty()) {
579 size_t p = vcomntools.find("\\Common7\\Tools");
580 if (p != std::string::npos)
581 vcomntools.resize(p);
582 path = std::move(vcomntools);
588 void MSVCToolChain::AddSystemIncludeWithSubfolder(
589 const ArgList &DriverArgs, ArgStringList &CC1Args,
590 const std::string &folder, const Twine &subfolder1, const Twine &subfolder2,
591 const Twine &subfolder3) const {
592 llvm::SmallString<128> path(folder);
593 llvm::sys::path::append(path, subfolder1, subfolder2, subfolder3);
594 addSystemInclude(DriverArgs, CC1Args, path);
597 void MSVCToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
598 ArgStringList &CC1Args) const {
599 if (DriverArgs.hasArg(options::OPT_nostdinc))
602 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
603 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, getDriver().ResourceDir,
607 // Add %INCLUDE%-like directories from the -imsvc flag.
608 for (const auto &Path : DriverArgs.getAllArgValues(options::OPT__SLASH_imsvc))
609 addSystemInclude(DriverArgs, CC1Args, Path);
611 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
614 // Honor %INCLUDE%. It should know essential search paths with vcvarsall.bat.
615 if (llvm::Optional<std::string> cl_include_dir =
616 llvm::sys::Process::GetEnv("INCLUDE")) {
617 SmallVector<StringRef, 8> Dirs;
618 StringRef(*cl_include_dir)
619 .split(Dirs, ";", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
620 for (StringRef Dir : Dirs)
621 addSystemInclude(DriverArgs, CC1Args, Dir);
628 // When built with access to the proper Windows APIs, try to actually find
629 // the correct include paths first.
630 if (getVisualStudioInstallDir(VSDir)) {
631 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, VSDir, "VC\\include");
633 if (useUniversalCRT(VSDir)) {
634 std::string UniversalCRTSdkPath;
635 std::string UCRTVersion;
636 if (getUniversalCRTSdkDir(UniversalCRTSdkPath, UCRTVersion)) {
637 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, UniversalCRTSdkPath,
638 "Include", UCRTVersion, "ucrt");
642 std::string WindowsSDKDir;
644 std::string windowsSDKIncludeVersion;
645 std::string windowsSDKLibVersion;
646 if (getWindowsSDKDir(WindowsSDKDir, major, windowsSDKIncludeVersion,
647 windowsSDKLibVersion)) {
649 // Note: windowsSDKIncludeVersion is empty for SDKs prior to v10.
650 // Anyway, llvm::sys::path::append is able to manage it.
651 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
652 "include", windowsSDKIncludeVersion,
654 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
655 "include", windowsSDKIncludeVersion,
657 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
658 "include", windowsSDKIncludeVersion,
661 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
665 addSystemInclude(DriverArgs, CC1Args, VSDir);
670 #if defined(LLVM_ON_WIN32)
671 // As a fallback, select default install paths.
672 // FIXME: Don't guess drives and paths like this on Windows.
673 const StringRef Paths[] = {
674 "C:/Program Files/Microsoft Visual Studio 10.0/VC/include",
675 "C:/Program Files/Microsoft Visual Studio 9.0/VC/include",
676 "C:/Program Files/Microsoft Visual Studio 9.0/VC/PlatformSDK/Include",
677 "C:/Program Files/Microsoft Visual Studio 8/VC/include",
678 "C:/Program Files/Microsoft Visual Studio 8/VC/PlatformSDK/Include"
680 addSystemIncludes(DriverArgs, CC1Args, Paths);
684 void MSVCToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
685 ArgStringList &CC1Args) const {
686 // FIXME: There should probably be logic here to find libc++ on Windows.
689 VersionTuple MSVCToolChain::computeMSVCVersion(const Driver *D,
690 const ArgList &Args) const {
691 bool IsWindowsMSVC = getTriple().isWindowsMSVCEnvironment();
692 VersionTuple MSVT = ToolChain::computeMSVCVersion(D, Args);
693 if (MSVT.empty()) MSVT = getMSVCVersionFromTriple();
694 if (MSVT.empty() && IsWindowsMSVC) MSVT = getMSVCVersionFromExe();
696 Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions,
698 // -fms-compatibility-version=18.00 is default.
699 // FIXME: Consider bumping this to 19 (MSVC2015) soon.
700 MSVT = VersionTuple(18);
706 MSVCToolChain::ComputeEffectiveClangTriple(const ArgList &Args,
707 types::ID InputType) const {
708 // The MSVC version doesn't care about the architecture, even though it
709 // may look at the triple internally.
710 VersionTuple MSVT = computeMSVCVersion(/*D=*/nullptr, Args);
711 MSVT = VersionTuple(MSVT.getMajor(), MSVT.getMinor().getValueOr(0),
712 MSVT.getSubminor().getValueOr(0));
714 // For the rest of the triple, however, a computed architecture name may
716 llvm::Triple Triple(ToolChain::ComputeEffectiveClangTriple(Args, InputType));
717 if (Triple.getEnvironment() == llvm::Triple::MSVC) {
718 StringRef ObjFmt = Triple.getEnvironmentName().split('-').second;
720 Triple.setEnvironmentName((Twine("msvc") + MSVT.getAsString()).str());
722 Triple.setEnvironmentName(
723 (Twine("msvc") + MSVT.getAsString() + Twine('-') + ObjFmt).str());
725 return Triple.getTriple();
728 SanitizerMask MSVCToolChain::getSupportedSanitizers() const {
729 SanitizerMask Res = ToolChain::getSupportedSanitizers();
730 Res |= SanitizerKind::Address;
734 static void TranslateOptArg(Arg *A, llvm::opt::DerivedArgList &DAL,
735 bool SupportsForcingFramePointer,
736 const char *ExpandChar, const OptTable &Opts) {
737 assert(A->getOption().matches(options::OPT__SLASH_O));
739 StringRef OptStr = A->getValue();
740 for (size_t I = 0, E = OptStr.size(); I != E; ++I) {
741 const char &OptChar = *(OptStr.data() + I);
749 if (&OptChar == ExpandChar) {
750 if (OptChar == 'd') {
751 DAL.AddFlagArg(A, Opts.getOption(options::OPT_O0));
753 if (OptChar == '1') {
754 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "s");
755 } else if (OptChar == '2' || OptChar == 'x') {
756 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
757 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "2");
759 if (SupportsForcingFramePointer &&
760 !DAL.hasArgNoClaim(options::OPT_fno_omit_frame_pointer))
762 Opts.getOption(options::OPT_fomit_frame_pointer));
763 if (OptChar == '1' || OptChar == '2')
765 Opts.getOption(options::OPT_ffunction_sections));
770 if (I + 1 != E && isdigit(OptStr[I + 1])) {
771 switch (OptStr[I + 1]) {
773 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_inline));
776 DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_hint_functions));
779 DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_functions));
788 if (I + 1 != E && OptStr[I + 1] == '-') {
790 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_builtin));
792 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
796 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "s");
799 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "2");
802 bool OmitFramePointer = true;
803 if (I + 1 != E && OptStr[I + 1] == '-') {
804 OmitFramePointer = false;
807 if (SupportsForcingFramePointer) {
808 if (OmitFramePointer)
810 Opts.getOption(options::OPT_fomit_frame_pointer));
813 A, Opts.getOption(options::OPT_fno_omit_frame_pointer));
815 // Don't warn about /Oy- in 64-bit builds (where
816 // SupportsForcingFramePointer is false). The flag having no effect
817 // there is a compiler-internal optimization, and people shouldn't have
818 // to special-case their build files for 64-bit clang-cl.
827 static void TranslateDArg(Arg *A, llvm::opt::DerivedArgList &DAL,
828 const OptTable &Opts) {
829 assert(A->getOption().matches(options::OPT_D));
831 StringRef Val = A->getValue();
832 size_t Hash = Val.find('#');
833 if (Hash == StringRef::npos || Hash > Val.find('=')) {
838 std::string NewVal = Val;
840 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_D), NewVal);
843 llvm::opt::DerivedArgList *
844 MSVCToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args,
845 StringRef BoundArch, Action::OffloadKind) const {
846 DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
847 const OptTable &Opts = getDriver().getOpts();
849 // /Oy and /Oy- only has an effect under X86-32.
850 bool SupportsForcingFramePointer = getArch() == llvm::Triple::x86;
852 // The -O[12xd] flag actually expands to several flags. We must desugar the
853 // flags so that options embedded can be negated. For example, the '-O2' flag
854 // enables '-Oy'. Expanding '-O2' into its constituent flags allows us to
855 // correctly handle '-O2 -Oy-' where the trailing '-Oy-' disables a single
858 // Note that this expansion logic only applies to the *last* of '[12xd]'.
860 // First step is to search for the character we'd like to expand.
861 const char *ExpandChar = nullptr;
862 for (Arg *A : Args) {
863 if (!A->getOption().matches(options::OPT__SLASH_O))
865 StringRef OptStr = A->getValue();
866 for (size_t I = 0, E = OptStr.size(); I != E; ++I) {
867 char OptChar = OptStr[I];
868 char PrevChar = I > 0 ? OptStr[I - 1] : '0';
869 if (PrevChar == 'b') {
870 // OptChar does not expand; it's an argument to the previous char.
873 if (OptChar == '1' || OptChar == '2' || OptChar == 'x' || OptChar == 'd')
874 ExpandChar = OptStr.data() + I;
878 for (Arg *A : Args) {
879 if (A->getOption().matches(options::OPT__SLASH_O)) {
880 // The -O flag actually takes an amalgam of other options. For example,
881 // '/Ogyb2' is equivalent to '/Og' '/Oy' '/Ob2'.
882 TranslateOptArg(A, *DAL, SupportsForcingFramePointer, ExpandChar, Opts);
883 } else if (A->getOption().matches(options::OPT_D)) {
884 // Translate -Dfoo#bar into -Dfoo=bar.
885 TranslateDArg(A, *DAL, Opts);