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) {
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;
98 static bool readFullStringValue(HKEY hkey, const char *valueName,
100 std::wstring WideValueName;
101 if (!llvm::ConvertUTF8toWide(valueName, WideValueName))
107 // First just query for the required size.
108 result = RegQueryValueExW(hkey, WideValueName.c_str(), NULL, &type, NULL,
110 if (result != ERROR_SUCCESS || type != REG_SZ || !valueSize)
112 std::vector<BYTE> buffer(valueSize);
113 result = RegQueryValueExW(hkey, WideValueName.c_str(), NULL, NULL, &buffer[0],
115 if (result == ERROR_SUCCESS) {
116 std::wstring WideValue(reinterpret_cast<const wchar_t *>(buffer.data()),
117 valueSize / sizeof(wchar_t));
118 if (valueSize && WideValue.back() == L'\0') {
119 WideValue.pop_back();
121 // The destination buffer must be empty as an invariant of the conversion
122 // function; but this function is sometimes called in a loop that passes in
123 // the same buffer, however. Simply clear it out so we can overwrite it.
125 return llvm::convertWideToUTF8(WideValue, value);
131 /// \brief Read registry string.
132 /// This also supports a means to look for high-versioned keys by use
133 /// of a $VERSION placeholder in the key path.
134 /// $VERSION in the key path is a placeholder for the version number,
135 /// causing the highest value path to be searched for and used.
136 /// I.e. "SOFTWARE\\Microsoft\\VisualStudio\\$VERSION".
137 /// There can be additional characters in the component. Only the numeric
138 /// characters are compared. This function only searches HKLM.
139 static bool getSystemRegistryString(const char *keyPath, const char *valueName,
140 std::string &value, std::string *phValue) {
144 HKEY hRootKey = HKEY_LOCAL_MACHINE;
147 bool returnValue = false;
149 const char *placeHolder = strstr(keyPath, "$VERSION");
150 std::string bestName;
151 // If we have a $VERSION placeholder, do the highest-version search.
153 const char *keyEnd = placeHolder - 1;
154 const char *nextKey = placeHolder;
155 // Find end of previous key.
156 while ((keyEnd > keyPath) && (*keyEnd != '\\'))
158 // Find end of key containing $VERSION.
159 while (*nextKey && (*nextKey != '\\'))
161 size_t partialKeyLength = keyEnd - keyPath;
162 char partialKey[256];
163 if (partialKeyLength >= sizeof(partialKey))
164 partialKeyLength = sizeof(partialKey) - 1;
165 strncpy(partialKey, keyPath, partialKeyLength);
166 partialKey[partialKeyLength] = '\0';
168 lResult = RegOpenKeyExA(hRootKey, partialKey, 0, KEY_READ | KEY_WOW64_32KEY,
170 if (lResult == ERROR_SUCCESS) {
172 double bestValue = 0.0;
173 DWORD index, size = sizeof(keyName) - 1;
174 for (index = 0; RegEnumKeyExA(hTopKey, index, keyName, &size, NULL, NULL,
175 NULL, NULL) == ERROR_SUCCESS;
177 const char *sp = keyName;
178 while (*sp && !isDigit(*sp))
182 const char *ep = sp + 1;
183 while (*ep && (isDigit(*ep) || (*ep == '.')))
186 strncpy(numBuf, sp, sizeof(numBuf) - 1);
187 numBuf[sizeof(numBuf) - 1] = '\0';
188 double dvalue = strtod(numBuf, NULL);
189 if (dvalue > bestValue) {
190 // Test that InstallDir is indeed there before keeping this index.
191 // Open the chosen key path remainder.
193 // Append rest of key.
194 bestName.append(nextKey);
195 lResult = RegOpenKeyExA(hTopKey, bestName.c_str(), 0,
196 KEY_READ | KEY_WOW64_32KEY, &hKey);
197 if (lResult == ERROR_SUCCESS) {
198 if (readFullStringValue(hKey, valueName, value)) {
207 size = sizeof(keyName) - 1;
209 RegCloseKey(hTopKey);
213 RegOpenKeyExA(hRootKey, keyPath, 0, KEY_READ | KEY_WOW64_32KEY, &hKey);
214 if (lResult == ERROR_SUCCESS) {
215 if (readFullStringValue(hKey, valueName, value))
226 // Convert LLVM's ArchType
227 // to the corresponding name of Windows SDK libraries subfolder
228 static StringRef getWindowsSDKArch(llvm::Triple::ArchType Arch) {
230 case llvm::Triple::x86:
232 case llvm::Triple::x86_64:
234 case llvm::Triple::arm:
241 // Find the most recent version of Universal CRT or Windows 10 SDK.
242 // vcvarsqueryregistry.bat from Visual Studio 2015 sorts entries in the include
243 // directory by name and uses the last one of the list.
244 // So we compare entry names lexicographically to find the greatest one.
245 static bool getWindows10SDKVersion(const std::string &SDKPath,
246 std::string &SDKVersion) {
250 llvm::SmallString<128> IncludePath(SDKPath);
251 llvm::sys::path::append(IncludePath, "Include");
252 for (llvm::sys::fs::directory_iterator DirIt(IncludePath, EC), DirEnd;
253 DirIt != DirEnd && !EC; DirIt.increment(EC)) {
254 if (!llvm::sys::fs::is_directory(DirIt->path()))
256 StringRef CandidateName = llvm::sys::path::filename(DirIt->path());
257 // If WDK is installed, there could be subfolders like "wdf" in the
258 // "Include" directory.
259 // Allow only directories which names start with "10.".
260 if (!CandidateName.startswith("10."))
262 if (CandidateName > SDKVersion)
263 SDKVersion = CandidateName;
266 return !SDKVersion.empty();
269 /// \brief Get Windows SDK installation directory.
270 bool MSVCToolChain::getWindowsSDKDir(std::string &Path, int &Major,
271 std::string &WindowsSDKIncludeVersion,
272 std::string &WindowsSDKLibVersion) const {
273 std::string RegistrySDKVersion;
274 // Try the Windows registry.
275 if (!getSystemRegistryString(
276 "SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\$VERSION",
277 "InstallationFolder", Path, &RegistrySDKVersion))
279 if (Path.empty() || RegistrySDKVersion.empty())
282 WindowsSDKIncludeVersion.clear();
283 WindowsSDKLibVersion.clear();
285 std::sscanf(RegistrySDKVersion.c_str(), "v%d.", &Major);
289 // Windows SDK 8.x installs libraries in a folder whose names depend on the
290 // version of the OS you're targeting. By default choose the newest, which
291 // usually corresponds to the version of the OS you've installed the SDK on.
292 const char *Tests[] = {"winv6.3", "win8", "win7"};
293 for (const char *Test : Tests) {
294 llvm::SmallString<128> TestPath(Path);
295 llvm::sys::path::append(TestPath, "Lib", Test);
296 if (llvm::sys::fs::exists(TestPath.c_str())) {
297 WindowsSDKLibVersion = Test;
301 return !WindowsSDKLibVersion.empty();
304 if (!getWindows10SDKVersion(Path, WindowsSDKIncludeVersion))
306 WindowsSDKLibVersion = WindowsSDKIncludeVersion;
309 // Unsupported SDK version
313 // Gets the library path required to link against the Windows SDK.
314 bool MSVCToolChain::getWindowsSDKLibraryPath(std::string &path) const {
317 std::string windowsSDKIncludeVersion;
318 std::string windowsSDKLibVersion;
321 if (!getWindowsSDKDir(sdkPath, sdkMajor, windowsSDKIncludeVersion,
322 windowsSDKLibVersion))
325 llvm::SmallString<128> libPath(sdkPath);
326 llvm::sys::path::append(libPath, "Lib");
329 // In Windows SDK 7.x, x86 libraries are directly in the Lib folder.
330 case llvm::Triple::x86:
332 case llvm::Triple::x86_64:
333 llvm::sys::path::append(libPath, "x64");
335 case llvm::Triple::arm:
336 // It is not necessary to link against Windows SDK 7.x when targeting ARM.
342 const StringRef archName = getWindowsSDKArch(getArch());
343 if (archName.empty())
345 llvm::sys::path::append(libPath, windowsSDKLibVersion, "um", archName);
348 path = libPath.str();
352 // Check if the Include path of a specified version of Visual Studio contains
353 // specific header files. If not, they are probably shipped with Universal CRT.
354 bool clang::driver::toolchains::MSVCToolChain::useUniversalCRT(
355 std::string &VisualStudioDir) const {
356 llvm::SmallString<128> TestPath(VisualStudioDir);
357 llvm::sys::path::append(TestPath, "VC\\include\\stdlib.h");
359 return !llvm::sys::fs::exists(TestPath);
362 bool MSVCToolChain::getUniversalCRTSdkDir(std::string &Path,
363 std::string &UCRTVersion) const {
364 // vcvarsqueryregistry.bat for Visual Studio 2015 queries the registry
365 // for the specific key "KitsRoot10". So do we.
366 if (!getSystemRegistryString(
367 "SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots", "KitsRoot10",
371 return getWindows10SDKVersion(Path, UCRTVersion);
374 bool MSVCToolChain::getUniversalCRTLibraryPath(std::string &Path) const {
375 std::string UniversalCRTSdkPath;
376 std::string UCRTVersion;
379 if (!getUniversalCRTSdkDir(UniversalCRTSdkPath, UCRTVersion))
382 StringRef ArchName = getWindowsSDKArch(getArch());
383 if (ArchName.empty())
386 llvm::SmallString<128> LibPath(UniversalCRTSdkPath);
387 llvm::sys::path::append(LibPath, "Lib", UCRTVersion, "ucrt", ArchName);
389 Path = LibPath.str();
393 // Get the location to use for Visual Studio binaries. The location priority
394 // is: %VCINSTALLDIR% > %PATH% > newest copy of Visual Studio installed on
395 // system (as reported by the registry).
396 bool MSVCToolChain::getVisualStudioBinariesFolder(const char *clangProgramPath,
397 std::string &path) const {
400 SmallString<128> BinDir;
402 // First check the environment variables that vsvars32.bat sets.
403 llvm::Optional<std::string> VcInstallDir =
404 llvm::sys::Process::GetEnv("VCINSTALLDIR");
405 if (VcInstallDir.hasValue()) {
406 BinDir = VcInstallDir.getValue();
407 llvm::sys::path::append(BinDir, "bin");
409 // Next walk the PATH, trying to find a cl.exe in the path. If we find one,
410 // use that. However, make sure it's not clang's cl.exe.
411 llvm::Optional<std::string> OptPath = llvm::sys::Process::GetEnv("PATH");
412 if (OptPath.hasValue()) {
413 const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'};
414 SmallVector<StringRef, 8> PathSegments;
415 llvm::SplitString(OptPath.getValue(), PathSegments, EnvPathSeparatorStr);
417 for (StringRef PathSegment : PathSegments) {
418 if (PathSegment.empty())
421 SmallString<128> FilePath(PathSegment);
422 llvm::sys::path::append(FilePath, "cl.exe");
423 // Checking if cl.exe exists is a small optimization over calling
424 // can_execute, which really only checks for existence but will also do
425 // extra checks for cl.exe.exe. These add up when walking a long path.
426 if (llvm::sys::fs::exists(FilePath.c_str()) &&
427 !llvm::sys::fs::equivalent(FilePath.c_str(), clangProgramPath)) {
428 // If we found it on the PATH, use it exactly as is with no
436 std::string installDir;
437 // With no VCINSTALLDIR and nothing on the PATH, if we can't find it in the
438 // registry then we have no choice but to fail.
439 if (!getVisualStudioInstallDir(installDir))
442 // Regardless of what binary we're ultimately trying to find, we make sure
443 // that this is a Visual Studio directory by checking for cl.exe. We use
444 // cl.exe instead of other binaries like link.exe because programs such as
445 // GnuWin32 also have a utility called link.exe, so cl.exe is the least
448 llvm::sys::path::append(BinDir, "VC", "bin");
449 SmallString<128> ClPath(BinDir);
450 llvm::sys::path::append(ClPath, "cl.exe");
452 if (!llvm::sys::fs::can_execute(ClPath.c_str()))
460 case llvm::Triple::x86:
462 case llvm::Triple::x86_64:
463 llvm::sys::path::append(BinDir, "amd64");
465 case llvm::Triple::arm:
466 llvm::sys::path::append(BinDir, "arm");
469 // Whatever this is, Visual Studio doesn't have a toolchain for it.
476 VersionTuple MSVCToolChain::getMSVCVersionFromTriple() const {
477 unsigned Major, Minor, Micro;
478 getTriple().getEnvironmentVersion(Major, Minor, Micro);
479 if (Major || Minor || Micro)
480 return VersionTuple(Major, Minor, Micro);
481 return VersionTuple();
484 VersionTuple MSVCToolChain::getMSVCVersionFromExe() const {
485 VersionTuple Version;
488 if (!getVisualStudioBinariesFolder("", BinPath))
490 SmallString<128> ClExe(BinPath);
491 llvm::sys::path::append(ClExe, "cl.exe");
493 std::wstring ClExeWide;
494 if (!llvm::ConvertUTF8toWide(ClExe.c_str(), ClExeWide))
497 const DWORD VersionSize = ::GetFileVersionInfoSizeW(ClExeWide.c_str(),
499 if (VersionSize == 0)
502 SmallVector<uint8_t, 4 * 1024> VersionBlock(VersionSize);
503 if (!::GetFileVersionInfoW(ClExeWide.c_str(), 0, VersionSize,
504 VersionBlock.data()))
507 VS_FIXEDFILEINFO *FileInfo = nullptr;
508 UINT FileInfoSize = 0;
509 if (!::VerQueryValueW(VersionBlock.data(), L"\\",
510 reinterpret_cast<LPVOID *>(&FileInfo), &FileInfoSize) ||
511 FileInfoSize < sizeof(*FileInfo))
514 const unsigned Major = (FileInfo->dwFileVersionMS >> 16) & 0xFFFF;
515 const unsigned Minor = (FileInfo->dwFileVersionMS ) & 0xFFFF;
516 const unsigned Micro = (FileInfo->dwFileVersionLS >> 16) & 0xFFFF;
518 Version = VersionTuple(Major, Minor, Micro);
523 // Get Visual Studio installation directory.
524 bool MSVCToolChain::getVisualStudioInstallDir(std::string &path) const {
525 // First check the environment variables that vsvars32.bat sets.
526 if (llvm::Optional<std::string> VcInstallDir =
527 llvm::sys::Process::GetEnv("VCINSTALLDIR")) {
528 path = std::move(*VcInstallDir);
529 path = path.substr(0, path.find("\\VC"));
533 std::string vsIDEInstallDir;
534 std::string vsExpressIDEInstallDir;
535 // Then try the windows registry.
537 getSystemRegistryString("SOFTWARE\\Microsoft\\VisualStudio\\$VERSION",
538 "InstallDir", vsIDEInstallDir, nullptr);
539 if (hasVCDir && !vsIDEInstallDir.empty()) {
540 path = vsIDEInstallDir.substr(0, vsIDEInstallDir.find("\\Common7\\IDE"));
544 bool hasVCExpressDir =
545 getSystemRegistryString("SOFTWARE\\Microsoft\\VCExpress\\$VERSION",
546 "InstallDir", vsExpressIDEInstallDir, nullptr);
547 if (hasVCExpressDir && !vsExpressIDEInstallDir.empty()) {
548 path = vsExpressIDEInstallDir.substr(
549 0, vsIDEInstallDir.find("\\Common7\\IDE"));
553 // Try the environment.
554 std::string vcomntools;
555 if (llvm::Optional<std::string> vs120comntools =
556 llvm::sys::Process::GetEnv("VS120COMNTOOLS"))
557 vcomntools = std::move(*vs120comntools);
558 else if (llvm::Optional<std::string> vs100comntools =
559 llvm::sys::Process::GetEnv("VS100COMNTOOLS"))
560 vcomntools = std::move(*vs100comntools);
561 else if (llvm::Optional<std::string> vs90comntools =
562 llvm::sys::Process::GetEnv("VS90COMNTOOLS"))
563 vcomntools = std::move(*vs90comntools);
564 else if (llvm::Optional<std::string> vs80comntools =
565 llvm::sys::Process::GetEnv("VS80COMNTOOLS"))
566 vcomntools = std::move(*vs80comntools);
568 // Find any version we can.
569 if (!vcomntools.empty()) {
570 size_t p = vcomntools.find("\\Common7\\Tools");
571 if (p != std::string::npos)
572 vcomntools.resize(p);
573 path = std::move(vcomntools);
579 void MSVCToolChain::AddSystemIncludeWithSubfolder(
580 const ArgList &DriverArgs, ArgStringList &CC1Args,
581 const std::string &folder, const Twine &subfolder1, const Twine &subfolder2,
582 const Twine &subfolder3) const {
583 llvm::SmallString<128> path(folder);
584 llvm::sys::path::append(path, subfolder1, subfolder2, subfolder3);
585 addSystemInclude(DriverArgs, CC1Args, path);
588 void MSVCToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
589 ArgStringList &CC1Args) const {
590 if (DriverArgs.hasArg(options::OPT_nostdinc))
593 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
594 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, getDriver().ResourceDir,
598 // Add %INCLUDE%-like directories from the -imsvc flag.
599 for (const auto &Path : DriverArgs.getAllArgValues(options::OPT__SLASH_imsvc))
600 addSystemInclude(DriverArgs, CC1Args, Path);
602 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
605 // Honor %INCLUDE%. It should know essential search paths with vcvarsall.bat.
606 if (llvm::Optional<std::string> cl_include_dir =
607 llvm::sys::Process::GetEnv("INCLUDE")) {
608 SmallVector<StringRef, 8> Dirs;
609 StringRef(*cl_include_dir)
610 .split(Dirs, ";", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
611 for (StringRef Dir : Dirs)
612 addSystemInclude(DriverArgs, CC1Args, Dir);
619 // When built with access to the proper Windows APIs, try to actually find
620 // the correct include paths first.
621 if (getVisualStudioInstallDir(VSDir)) {
622 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, VSDir, "VC\\include");
624 if (useUniversalCRT(VSDir)) {
625 std::string UniversalCRTSdkPath;
626 std::string UCRTVersion;
627 if (getUniversalCRTSdkDir(UniversalCRTSdkPath, UCRTVersion)) {
628 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, UniversalCRTSdkPath,
629 "Include", UCRTVersion, "ucrt");
633 std::string WindowsSDKDir;
635 std::string windowsSDKIncludeVersion;
636 std::string windowsSDKLibVersion;
637 if (getWindowsSDKDir(WindowsSDKDir, major, windowsSDKIncludeVersion,
638 windowsSDKLibVersion)) {
640 // Note: windowsSDKIncludeVersion is empty for SDKs prior to v10.
641 // Anyway, llvm::sys::path::append is able to manage it.
642 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
643 "include", windowsSDKIncludeVersion,
645 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
646 "include", windowsSDKIncludeVersion,
648 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
649 "include", windowsSDKIncludeVersion,
652 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
656 addSystemInclude(DriverArgs, CC1Args, VSDir);
661 #if defined(LLVM_ON_WIN32)
662 // As a fallback, select default install paths.
663 // FIXME: Don't guess drives and paths like this on Windows.
664 const StringRef Paths[] = {
665 "C:/Program Files/Microsoft Visual Studio 10.0/VC/include",
666 "C:/Program Files/Microsoft Visual Studio 9.0/VC/include",
667 "C:/Program Files/Microsoft Visual Studio 9.0/VC/PlatformSDK/Include",
668 "C:/Program Files/Microsoft Visual Studio 8/VC/include",
669 "C:/Program Files/Microsoft Visual Studio 8/VC/PlatformSDK/Include"
671 addSystemIncludes(DriverArgs, CC1Args, Paths);
675 void MSVCToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
676 ArgStringList &CC1Args) const {
677 // FIXME: There should probably be logic here to find libc++ on Windows.
680 VersionTuple MSVCToolChain::computeMSVCVersion(const Driver *D,
681 const ArgList &Args) const {
682 bool IsWindowsMSVC = getTriple().isWindowsMSVCEnvironment();
683 VersionTuple MSVT = ToolChain::computeMSVCVersion(D, Args);
684 if (MSVT.empty()) MSVT = getMSVCVersionFromTriple();
685 if (MSVT.empty() && IsWindowsMSVC) MSVT = getMSVCVersionFromExe();
687 Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions,
689 // -fms-compatibility-version=18.00 is default.
690 // FIXME: Consider bumping this to 19 (MSVC2015) soon.
691 MSVT = VersionTuple(18);
697 MSVCToolChain::ComputeEffectiveClangTriple(const ArgList &Args,
698 types::ID InputType) const {
699 // The MSVC version doesn't care about the architecture, even though it
700 // may look at the triple internally.
701 VersionTuple MSVT = computeMSVCVersion(/*D=*/nullptr, Args);
702 MSVT = VersionTuple(MSVT.getMajor(), MSVT.getMinor().getValueOr(0),
703 MSVT.getSubminor().getValueOr(0));
705 // For the rest of the triple, however, a computed architecture name may
707 llvm::Triple Triple(ToolChain::ComputeEffectiveClangTriple(Args, InputType));
708 if (Triple.getEnvironment() == llvm::Triple::MSVC) {
709 StringRef ObjFmt = Triple.getEnvironmentName().split('-').second;
711 Triple.setEnvironmentName((Twine("msvc") + MSVT.getAsString()).str());
713 Triple.setEnvironmentName(
714 (Twine("msvc") + MSVT.getAsString() + Twine('-') + ObjFmt).str());
716 return Triple.getTriple();
719 SanitizerMask MSVCToolChain::getSupportedSanitizers() const {
720 SanitizerMask Res = ToolChain::getSupportedSanitizers();
721 Res |= SanitizerKind::Address;
725 static void TranslateOptArg(Arg *A, llvm::opt::DerivedArgList &DAL,
726 bool SupportsForcingFramePointer,
727 const char *ExpandChar, const OptTable &Opts) {
728 assert(A->getOption().matches(options::OPT__SLASH_O));
730 StringRef OptStr = A->getValue();
731 for (size_t I = 0, E = OptStr.size(); I != E; ++I) {
732 const char &OptChar = *(OptStr.data() + I);
740 if (&OptChar == ExpandChar) {
741 if (OptChar == 'd') {
742 DAL.AddFlagArg(A, Opts.getOption(options::OPT_O0));
744 if (OptChar == '1') {
745 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "s");
746 } else if (OptChar == '2' || OptChar == 'x') {
747 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
748 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "2");
750 if (SupportsForcingFramePointer &&
751 !DAL.hasArgNoClaim(options::OPT_fno_omit_frame_pointer))
753 Opts.getOption(options::OPT_fomit_frame_pointer));
754 if (OptChar == '1' || OptChar == '2')
756 Opts.getOption(options::OPT_ffunction_sections));
761 if (I + 1 != E && isdigit(OptStr[I + 1])) {
762 switch (OptStr[I + 1]) {
764 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_inline));
767 DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_hint_functions));
770 DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_functions));
779 if (I + 1 != E && OptStr[I + 1] == '-') {
781 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_builtin));
783 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
787 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "s");
790 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "2");
793 bool OmitFramePointer = true;
794 if (I + 1 != E && OptStr[I + 1] == '-') {
795 OmitFramePointer = false;
798 if (SupportsForcingFramePointer) {
799 if (OmitFramePointer)
801 Opts.getOption(options::OPT_fomit_frame_pointer));
804 A, Opts.getOption(options::OPT_fno_omit_frame_pointer));
806 // Don't warn about /Oy- in 64-bit builds (where
807 // SupportsForcingFramePointer is false). The flag having no effect
808 // there is a compiler-internal optimization, and people shouldn't have
809 // to special-case their build files for 64-bit clang-cl.
818 static void TranslateDArg(Arg *A, llvm::opt::DerivedArgList &DAL,
819 const OptTable &Opts) {
820 assert(A->getOption().matches(options::OPT_D));
822 StringRef Val = A->getValue();
823 size_t Hash = Val.find('#');
824 if (Hash == StringRef::npos || Hash > Val.find('=')) {
829 std::string NewVal = Val;
831 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_D), NewVal);
834 llvm::opt::DerivedArgList *
835 MSVCToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args,
836 StringRef BoundArch, Action::OffloadKind) const {
837 DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
838 const OptTable &Opts = getDriver().getOpts();
840 // /Oy and /Oy- only has an effect under X86-32.
841 bool SupportsForcingFramePointer = getArch() == llvm::Triple::x86;
843 // The -O[12xd] flag actually expands to several flags. We must desugar the
844 // flags so that options embedded can be negated. For example, the '-O2' flag
845 // enables '-Oy'. Expanding '-O2' into its constituent flags allows us to
846 // correctly handle '-O2 -Oy-' where the trailing '-Oy-' disables a single
849 // Note that this expansion logic only applies to the *last* of '[12xd]'.
851 // First step is to search for the character we'd like to expand.
852 const char *ExpandChar = nullptr;
853 for (Arg *A : Args) {
854 if (!A->getOption().matches(options::OPT__SLASH_O))
856 StringRef OptStr = A->getValue();
857 for (size_t I = 0, E = OptStr.size(); I != E; ++I) {
858 char OptChar = OptStr[I];
859 char PrevChar = I > 0 ? OptStr[I - 1] : '0';
860 if (PrevChar == 'b') {
861 // OptChar does not expand; it's an argument to the previous char.
864 if (OptChar == '1' || OptChar == '2' || OptChar == 'x' || OptChar == 'd')
865 ExpandChar = OptStr.data() + I;
869 for (Arg *A : Args) {
870 if (A->getOption().matches(options::OPT__SLASH_O)) {
871 // The -O flag actually takes an amalgam of other options. For example,
872 // '/Ogyb2' is equivalent to '/Og' '/Oy' '/Ob2'.
873 TranslateOptArg(A, *DAL, SupportsForcingFramePointer, ExpandChar, Opts);
874 } else if (A->getOption().matches(options::OPT_D)) {
875 // Translate -Dfoo#bar into -Dfoo=bar.
876 TranslateDArg(A, *DAL, Opts);