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/Config/llvm-config.h"
20 #include "llvm/Option/Arg.h"
21 #include "llvm/Option/ArgList.h"
22 #include "llvm/Support/ConvertUTF.h"
23 #include "llvm/Support/ErrorHandling.h"
24 #include "llvm/Support/FileSystem.h"
25 #include "llvm/Support/Path.h"
26 #include "llvm/Support/Process.h"
29 // Include the necessary headers to interface with the Windows registry and
31 #if defined(LLVM_ON_WIN32)
36 #define WIN32_LEAN_AND_MEAN
44 using namespace clang::driver;
45 using namespace clang::driver::toolchains;
46 using namespace clang;
47 using namespace llvm::opt;
49 MSVCToolChain::MSVCToolChain(const Driver &D, const llvm::Triple& Triple,
51 : ToolChain(D, Triple, Args) {
52 getProgramPaths().push_back(getDriver().getInstalledDir());
53 if (getDriver().getInstalledDir() != getDriver().Dir)
54 getProgramPaths().push_back(getDriver().Dir);
57 Tool *MSVCToolChain::buildLinker() const {
58 return new tools::visualstudio::Linker(*this);
61 Tool *MSVCToolChain::buildAssembler() const {
62 if (getTriple().isOSBinFormatMachO())
63 return new tools::darwin::Assembler(*this);
64 getDriver().Diag(clang::diag::err_no_external_assembler);
68 bool MSVCToolChain::IsIntegratedAssemblerDefault() const {
72 bool MSVCToolChain::IsUnwindTablesDefault() const {
73 // Emit unwind tables by default on Win64. All non-x86_32 Windows platforms
74 // such as ARM and PPC actually require unwind tables, but LLVM doesn't know
75 // how to generate them yet.
77 // Don't emit unwind tables by default for MachO targets.
78 if (getTriple().isOSBinFormatMachO())
81 return getArch() == llvm::Triple::x86_64;
84 bool MSVCToolChain::isPICDefault() const {
85 return getArch() == llvm::Triple::x86_64;
88 bool MSVCToolChain::isPIEDefault() const {
92 bool MSVCToolChain::isPICDefaultForced() const {
93 return getArch() == llvm::Triple::x86_64;
97 static bool readFullStringValue(HKEY hkey, const char *valueName,
99 std::wstring WideValueName;
100 if (!llvm::ConvertUTF8toWide(valueName, WideValueName))
106 // First just query for the required size.
107 result = RegQueryValueExW(hkey, WideValueName.c_str(), NULL, &type, NULL,
109 if (result != ERROR_SUCCESS || type != REG_SZ || !valueSize)
111 std::vector<BYTE> buffer(valueSize);
112 result = RegQueryValueExW(hkey, WideValueName.c_str(), NULL, NULL, &buffer[0],
114 if (result == ERROR_SUCCESS) {
115 std::wstring WideValue(reinterpret_cast<const wchar_t *>(buffer.data()),
116 valueSize / sizeof(wchar_t));
117 if (valueSize && WideValue.back() == L'\0') {
118 WideValue.pop_back();
120 // The destination buffer must be empty as an invariant of the conversion
121 // function; but this function is sometimes called in a loop that passes in
122 // the same buffer, however. Simply clear it out so we can overwrite it.
124 return llvm::convertWideToUTF8(WideValue, value);
130 /// \brief Read registry string.
131 /// This also supports a means to look for high-versioned keys by use
132 /// of a $VERSION placeholder in the key path.
133 /// $VERSION in the key path is a placeholder for the version number,
134 /// causing the highest value path to be searched for and used.
135 /// I.e. "SOFTWARE\\Microsoft\\VisualStudio\\$VERSION".
136 /// There can be additional characters in the component. Only the numeric
137 /// characters are compared. This function only searches HKLM.
138 static bool getSystemRegistryString(const char *keyPath, const char *valueName,
139 std::string &value, std::string *phValue) {
143 HKEY hRootKey = HKEY_LOCAL_MACHINE;
146 bool returnValue = false;
148 const char *placeHolder = strstr(keyPath, "$VERSION");
149 std::string bestName;
150 // If we have a $VERSION placeholder, do the highest-version search.
152 const char *keyEnd = placeHolder - 1;
153 const char *nextKey = placeHolder;
154 // Find end of previous key.
155 while ((keyEnd > keyPath) && (*keyEnd != '\\'))
157 // Find end of key containing $VERSION.
158 while (*nextKey && (*nextKey != '\\'))
160 size_t partialKeyLength = keyEnd - keyPath;
161 char partialKey[256];
162 if (partialKeyLength >= sizeof(partialKey))
163 partialKeyLength = sizeof(partialKey) - 1;
164 strncpy(partialKey, keyPath, partialKeyLength);
165 partialKey[partialKeyLength] = '\0';
167 lResult = RegOpenKeyExA(hRootKey, partialKey, 0, KEY_READ | KEY_WOW64_32KEY,
169 if (lResult == ERROR_SUCCESS) {
171 double bestValue = 0.0;
172 DWORD index, size = sizeof(keyName) - 1;
173 for (index = 0; RegEnumKeyExA(hTopKey, index, keyName, &size, NULL, NULL,
174 NULL, NULL) == ERROR_SUCCESS;
176 const char *sp = keyName;
177 while (*sp && !isDigit(*sp))
181 const char *ep = sp + 1;
182 while (*ep && (isDigit(*ep) || (*ep == '.')))
185 strncpy(numBuf, sp, sizeof(numBuf) - 1);
186 numBuf[sizeof(numBuf) - 1] = '\0';
187 double dvalue = strtod(numBuf, NULL);
188 if (dvalue > bestValue) {
189 // Test that InstallDir is indeed there before keeping this index.
190 // Open the chosen key path remainder.
192 // Append rest of key.
193 bestName.append(nextKey);
194 lResult = RegOpenKeyExA(hTopKey, bestName.c_str(), 0,
195 KEY_READ | KEY_WOW64_32KEY, &hKey);
196 if (lResult == ERROR_SUCCESS) {
197 if (readFullStringValue(hKey, valueName, value)) {
206 size = sizeof(keyName) - 1;
208 RegCloseKey(hTopKey);
212 RegOpenKeyExA(hRootKey, keyPath, 0, KEY_READ | KEY_WOW64_32KEY, &hKey);
213 if (lResult == ERROR_SUCCESS) {
214 if (readFullStringValue(hKey, valueName, value))
225 // Convert LLVM's ArchType
226 // to the corresponding name of Windows SDK libraries subfolder
227 static StringRef getWindowsSDKArch(llvm::Triple::ArchType Arch) {
229 case llvm::Triple::x86:
231 case llvm::Triple::x86_64:
233 case llvm::Triple::arm:
240 // Find the most recent version of Universal CRT or Windows 10 SDK.
241 // vcvarsqueryregistry.bat from Visual Studio 2015 sorts entries in the include
242 // directory by name and uses the last one of the list.
243 // So we compare entry names lexicographically to find the greatest one.
244 static bool getWindows10SDKVersion(const std::string &SDKPath,
245 std::string &SDKVersion) {
249 llvm::SmallString<128> IncludePath(SDKPath);
250 llvm::sys::path::append(IncludePath, "Include");
251 for (llvm::sys::fs::directory_iterator DirIt(IncludePath, EC), DirEnd;
252 DirIt != DirEnd && !EC; DirIt.increment(EC)) {
253 if (!llvm::sys::fs::is_directory(DirIt->path()))
255 StringRef CandidateName = llvm::sys::path::filename(DirIt->path());
256 // If WDK is installed, there could be subfolders like "wdf" in the
257 // "Include" directory.
258 // Allow only directories which names start with "10.".
259 if (!CandidateName.startswith("10."))
261 if (CandidateName > SDKVersion)
262 SDKVersion = CandidateName;
265 return !SDKVersion.empty();
268 /// \brief Get Windows SDK installation directory.
269 bool MSVCToolChain::getWindowsSDKDir(std::string &Path, int &Major,
270 std::string &WindowsSDKIncludeVersion,
271 std::string &WindowsSDKLibVersion) const {
272 std::string RegistrySDKVersion;
273 // Try the Windows registry.
274 if (!getSystemRegistryString(
275 "SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\$VERSION",
276 "InstallationFolder", Path, &RegistrySDKVersion))
278 if (Path.empty() || RegistrySDKVersion.empty())
281 WindowsSDKIncludeVersion.clear();
282 WindowsSDKLibVersion.clear();
284 std::sscanf(RegistrySDKVersion.c_str(), "v%d.", &Major);
288 // Windows SDK 8.x installs libraries in a folder whose names depend on the
289 // version of the OS you're targeting. By default choose the newest, which
290 // usually corresponds to the version of the OS you've installed the SDK on.
291 const char *Tests[] = {"winv6.3", "win8", "win7"};
292 for (const char *Test : Tests) {
293 llvm::SmallString<128> TestPath(Path);
294 llvm::sys::path::append(TestPath, "Lib", Test);
295 if (llvm::sys::fs::exists(TestPath.c_str())) {
296 WindowsSDKLibVersion = Test;
300 return !WindowsSDKLibVersion.empty();
303 if (!getWindows10SDKVersion(Path, WindowsSDKIncludeVersion))
305 WindowsSDKLibVersion = WindowsSDKIncludeVersion;
308 // Unsupported SDK version
312 // Gets the library path required to link against the Windows SDK.
313 bool MSVCToolChain::getWindowsSDKLibraryPath(std::string &path) const {
316 std::string windowsSDKIncludeVersion;
317 std::string windowsSDKLibVersion;
320 if (!getWindowsSDKDir(sdkPath, sdkMajor, windowsSDKIncludeVersion,
321 windowsSDKLibVersion))
324 llvm::SmallString<128> libPath(sdkPath);
325 llvm::sys::path::append(libPath, "Lib");
328 // In Windows SDK 7.x, x86 libraries are directly in the Lib folder.
329 case llvm::Triple::x86:
331 case llvm::Triple::x86_64:
332 llvm::sys::path::append(libPath, "x64");
334 case llvm::Triple::arm:
335 // It is not necessary to link against Windows SDK 7.x when targeting ARM.
341 const StringRef archName = getWindowsSDKArch(getArch());
342 if (archName.empty())
344 llvm::sys::path::append(libPath, windowsSDKLibVersion, "um", archName);
347 path = libPath.str();
351 // Check if the Include path of a specified version of Visual Studio contains
352 // specific header files. If not, they are probably shipped with Universal CRT.
353 bool clang::driver::toolchains::MSVCToolChain::useUniversalCRT(
354 std::string &VisualStudioDir) const {
355 llvm::SmallString<128> TestPath(VisualStudioDir);
356 llvm::sys::path::append(TestPath, "VC\\include\\stdlib.h");
358 return !llvm::sys::fs::exists(TestPath);
361 bool MSVCToolChain::getUniversalCRTSdkDir(std::string &Path,
362 std::string &UCRTVersion) const {
363 // vcvarsqueryregistry.bat for Visual Studio 2015 queries the registry
364 // for the specific key "KitsRoot10". So do we.
365 if (!getSystemRegistryString(
366 "SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots", "KitsRoot10",
370 return getWindows10SDKVersion(Path, UCRTVersion);
373 bool MSVCToolChain::getUniversalCRTLibraryPath(std::string &Path) const {
374 std::string UniversalCRTSdkPath;
375 std::string UCRTVersion;
378 if (!getUniversalCRTSdkDir(UniversalCRTSdkPath, UCRTVersion))
381 StringRef ArchName = getWindowsSDKArch(getArch());
382 if (ArchName.empty())
385 llvm::SmallString<128> LibPath(UniversalCRTSdkPath);
386 llvm::sys::path::append(LibPath, "Lib", UCRTVersion, "ucrt", ArchName);
388 Path = LibPath.str();
392 // Get the location to use for Visual Studio binaries. The location priority
393 // is: %VCINSTALLDIR% > %PATH% > newest copy of Visual Studio installed on
394 // system (as reported by the registry).
395 bool MSVCToolChain::getVisualStudioBinariesFolder(const char *clangProgramPath,
396 std::string &path) const {
399 SmallString<128> BinDir;
401 // First check the environment variables that vsvars32.bat sets.
402 llvm::Optional<std::string> VcInstallDir =
403 llvm::sys::Process::GetEnv("VCINSTALLDIR");
404 if (VcInstallDir.hasValue()) {
405 BinDir = VcInstallDir.getValue();
406 llvm::sys::path::append(BinDir, "bin");
408 // Next walk the PATH, trying to find a cl.exe in the path. If we find one,
409 // use that. However, make sure it's not clang's cl.exe.
410 llvm::Optional<std::string> OptPath = llvm::sys::Process::GetEnv("PATH");
411 if (OptPath.hasValue()) {
412 const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'};
413 SmallVector<StringRef, 8> PathSegments;
414 llvm::SplitString(OptPath.getValue(), PathSegments, EnvPathSeparatorStr);
416 for (StringRef PathSegment : PathSegments) {
417 if (PathSegment.empty())
420 SmallString<128> FilePath(PathSegment);
421 llvm::sys::path::append(FilePath, "cl.exe");
422 // Checking if cl.exe exists is a small optimization over calling
423 // can_execute, which really only checks for existence but will also do
424 // extra checks for cl.exe.exe. These add up when walking a long path.
425 if (llvm::sys::fs::exists(FilePath.c_str()) &&
426 !llvm::sys::fs::equivalent(FilePath.c_str(), clangProgramPath)) {
427 // If we found it on the PATH, use it exactly as is with no
435 std::string installDir;
436 // With no VCINSTALLDIR and nothing on the PATH, if we can't find it in the
437 // registry then we have no choice but to fail.
438 if (!getVisualStudioInstallDir(installDir))
441 // Regardless of what binary we're ultimately trying to find, we make sure
442 // that this is a Visual Studio directory by checking for cl.exe. We use
443 // cl.exe instead of other binaries like link.exe because programs such as
444 // GnuWin32 also have a utility called link.exe, so cl.exe is the least
447 llvm::sys::path::append(BinDir, "VC", "bin");
448 SmallString<128> ClPath(BinDir);
449 llvm::sys::path::append(ClPath, "cl.exe");
451 if (!llvm::sys::fs::can_execute(ClPath.c_str()))
459 case llvm::Triple::x86:
461 case llvm::Triple::x86_64:
462 llvm::sys::path::append(BinDir, "amd64");
464 case llvm::Triple::arm:
465 llvm::sys::path::append(BinDir, "arm");
468 // Whatever this is, Visual Studio doesn't have a toolchain for it.
475 VersionTuple MSVCToolChain::getMSVCVersionFromExe() const {
476 VersionTuple Version;
479 if (!getVisualStudioBinariesFolder("", BinPath))
481 SmallString<128> ClExe(BinPath);
482 llvm::sys::path::append(ClExe, "cl.exe");
484 std::wstring ClExeWide;
485 if (!llvm::ConvertUTF8toWide(ClExe.c_str(), ClExeWide))
488 const DWORD VersionSize = ::GetFileVersionInfoSizeW(ClExeWide.c_str(),
490 if (VersionSize == 0)
493 SmallVector<uint8_t, 4 * 1024> VersionBlock(VersionSize);
494 if (!::GetFileVersionInfoW(ClExeWide.c_str(), 0, VersionSize,
495 VersionBlock.data()))
498 VS_FIXEDFILEINFO *FileInfo = nullptr;
499 UINT FileInfoSize = 0;
500 if (!::VerQueryValueW(VersionBlock.data(), L"\\",
501 reinterpret_cast<LPVOID *>(&FileInfo), &FileInfoSize) ||
502 FileInfoSize < sizeof(*FileInfo))
505 const unsigned Major = (FileInfo->dwFileVersionMS >> 16) & 0xFFFF;
506 const unsigned Minor = (FileInfo->dwFileVersionMS ) & 0xFFFF;
507 const unsigned Micro = (FileInfo->dwFileVersionLS >> 16) & 0xFFFF;
509 Version = VersionTuple(Major, Minor, Micro);
514 // Get Visual Studio installation directory.
515 bool MSVCToolChain::getVisualStudioInstallDir(std::string &path) const {
516 // First check the environment variables that vsvars32.bat sets.
517 if (llvm::Optional<std::string> VcInstallDir =
518 llvm::sys::Process::GetEnv("VCINSTALLDIR")) {
519 path = std::move(*VcInstallDir);
520 path = path.substr(0, path.find("\\VC"));
524 std::string vsIDEInstallDir;
525 std::string vsExpressIDEInstallDir;
526 // Then try the windows registry.
528 getSystemRegistryString("SOFTWARE\\Microsoft\\VisualStudio\\$VERSION",
529 "InstallDir", vsIDEInstallDir, nullptr);
530 if (hasVCDir && !vsIDEInstallDir.empty()) {
531 path = vsIDEInstallDir.substr(0, vsIDEInstallDir.find("\\Common7\\IDE"));
535 bool hasVCExpressDir =
536 getSystemRegistryString("SOFTWARE\\Microsoft\\VCExpress\\$VERSION",
537 "InstallDir", vsExpressIDEInstallDir, nullptr);
538 if (hasVCExpressDir && !vsExpressIDEInstallDir.empty()) {
539 path = vsExpressIDEInstallDir.substr(
540 0, vsIDEInstallDir.find("\\Common7\\IDE"));
544 // Try the environment.
545 std::string vcomntools;
546 if (llvm::Optional<std::string> vs120comntools =
547 llvm::sys::Process::GetEnv("VS120COMNTOOLS"))
548 vcomntools = std::move(*vs120comntools);
549 else if (llvm::Optional<std::string> vs100comntools =
550 llvm::sys::Process::GetEnv("VS100COMNTOOLS"))
551 vcomntools = std::move(*vs100comntools);
552 else if (llvm::Optional<std::string> vs90comntools =
553 llvm::sys::Process::GetEnv("VS90COMNTOOLS"))
554 vcomntools = std::move(*vs90comntools);
555 else if (llvm::Optional<std::string> vs80comntools =
556 llvm::sys::Process::GetEnv("VS80COMNTOOLS"))
557 vcomntools = std::move(*vs80comntools);
559 // Find any version we can.
560 if (!vcomntools.empty()) {
561 size_t p = vcomntools.find("\\Common7\\Tools");
562 if (p != std::string::npos)
563 vcomntools.resize(p);
564 path = std::move(vcomntools);
570 void MSVCToolChain::AddSystemIncludeWithSubfolder(
571 const ArgList &DriverArgs, ArgStringList &CC1Args,
572 const std::string &folder, const Twine &subfolder1, const Twine &subfolder2,
573 const Twine &subfolder3) const {
574 llvm::SmallString<128> path(folder);
575 llvm::sys::path::append(path, subfolder1, subfolder2, subfolder3);
576 addSystemInclude(DriverArgs, CC1Args, path);
579 void MSVCToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
580 ArgStringList &CC1Args) const {
581 if (DriverArgs.hasArg(options::OPT_nostdinc))
584 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
585 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, getDriver().ResourceDir,
589 // Add %INCLUDE%-like directories from the -imsvc flag.
590 for (const auto &Path : DriverArgs.getAllArgValues(options::OPT__SLASH_imsvc))
591 addSystemInclude(DriverArgs, CC1Args, Path);
593 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
596 // Honor %INCLUDE%. It should know essential search paths with vcvarsall.bat.
597 if (llvm::Optional<std::string> cl_include_dir =
598 llvm::sys::Process::GetEnv("INCLUDE")) {
599 SmallVector<StringRef, 8> Dirs;
600 StringRef(*cl_include_dir)
601 .split(Dirs, ";", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
602 for (StringRef Dir : Dirs)
603 addSystemInclude(DriverArgs, CC1Args, Dir);
610 // When built with access to the proper Windows APIs, try to actually find
611 // the correct include paths first.
612 if (getVisualStudioInstallDir(VSDir)) {
613 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, VSDir, "VC\\include");
615 if (useUniversalCRT(VSDir)) {
616 std::string UniversalCRTSdkPath;
617 std::string UCRTVersion;
618 if (getUniversalCRTSdkDir(UniversalCRTSdkPath, UCRTVersion)) {
619 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, UniversalCRTSdkPath,
620 "Include", UCRTVersion, "ucrt");
624 std::string WindowsSDKDir;
626 std::string windowsSDKIncludeVersion;
627 std::string windowsSDKLibVersion;
628 if (getWindowsSDKDir(WindowsSDKDir, major, windowsSDKIncludeVersion,
629 windowsSDKLibVersion)) {
631 // Note: windowsSDKIncludeVersion is empty for SDKs prior to v10.
632 // Anyway, llvm::sys::path::append is able to manage it.
633 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
634 "include", windowsSDKIncludeVersion,
636 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
637 "include", windowsSDKIncludeVersion,
639 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
640 "include", windowsSDKIncludeVersion,
643 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
647 addSystemInclude(DriverArgs, CC1Args, VSDir);
652 #if defined(LLVM_ON_WIN32)
653 // As a fallback, select default install paths.
654 // FIXME: Don't guess drives and paths like this on Windows.
655 const StringRef Paths[] = {
656 "C:/Program Files/Microsoft Visual Studio 10.0/VC/include",
657 "C:/Program Files/Microsoft Visual Studio 9.0/VC/include",
658 "C:/Program Files/Microsoft Visual Studio 9.0/VC/PlatformSDK/Include",
659 "C:/Program Files/Microsoft Visual Studio 8/VC/include",
660 "C:/Program Files/Microsoft Visual Studio 8/VC/PlatformSDK/Include"
662 addSystemIncludes(DriverArgs, CC1Args, Paths);
666 void MSVCToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
667 ArgStringList &CC1Args) const {
668 // FIXME: There should probably be logic here to find libc++ on Windows.
672 MSVCToolChain::ComputeEffectiveClangTriple(const ArgList &Args,
673 types::ID InputType) const {
674 std::string TripleStr =
675 ToolChain::ComputeEffectiveClangTriple(Args, InputType);
676 llvm::Triple Triple(TripleStr);
678 tools::visualstudio::getMSVCVersion(/*D=*/nullptr, *this, Triple, Args,
679 /*IsWindowsMSVC=*/true);
683 MSVT = VersionTuple(MSVT.getMajor(), MSVT.getMinor().getValueOr(0),
684 MSVT.getSubminor().getValueOr(0));
686 if (Triple.getEnvironment() == llvm::Triple::MSVC) {
687 StringRef ObjFmt = Triple.getEnvironmentName().split('-').second;
689 Triple.setEnvironmentName((Twine("msvc") + MSVT.getAsString()).str());
691 Triple.setEnvironmentName(
692 (Twine("msvc") + MSVT.getAsString() + Twine('-') + ObjFmt).str());
694 return Triple.getTriple();
697 SanitizerMask MSVCToolChain::getSupportedSanitizers() const {
698 SanitizerMask Res = ToolChain::getSupportedSanitizers();
699 Res |= SanitizerKind::Address;
703 static void TranslateOptArg(Arg *A, llvm::opt::DerivedArgList &DAL,
704 bool SupportsForcingFramePointer,
705 const char *ExpandChar, const OptTable &Opts) {
706 assert(A->getOption().matches(options::OPT__SLASH_O));
708 StringRef OptStr = A->getValue();
709 for (size_t I = 0, E = OptStr.size(); I != E; ++I) {
710 const char &OptChar = *(OptStr.data() + I);
718 if (&OptChar == ExpandChar) {
719 if (OptChar == 'd') {
720 DAL.AddFlagArg(A, Opts.getOption(options::OPT_O0));
722 if (OptChar == '1') {
723 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "s");
724 } else if (OptChar == '2' || OptChar == 'x') {
725 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
726 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "2");
728 if (SupportsForcingFramePointer &&
729 !DAL.hasArgNoClaim(options::OPT_fno_omit_frame_pointer))
731 Opts.getOption(options::OPT_fomit_frame_pointer));
732 if (OptChar == '1' || OptChar == '2')
734 Opts.getOption(options::OPT_ffunction_sections));
739 if (I + 1 != E && isdigit(OptStr[I + 1])) {
740 switch (OptStr[I + 1]) {
742 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_inline));
745 DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_hint_functions));
748 DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_functions));
757 if (I + 1 != E && OptStr[I + 1] == '-') {
759 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_builtin));
761 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
765 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "s");
768 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "2");
771 bool OmitFramePointer = true;
772 if (I + 1 != E && OptStr[I + 1] == '-') {
773 OmitFramePointer = false;
776 if (SupportsForcingFramePointer) {
777 if (OmitFramePointer)
779 Opts.getOption(options::OPT_fomit_frame_pointer));
782 A, Opts.getOption(options::OPT_fno_omit_frame_pointer));
784 // Don't warn about /Oy- in 64-bit builds (where
785 // SupportsForcingFramePointer is false). The flag having no effect
786 // there is a compiler-internal optimization, and people shouldn't have
787 // to special-case their build files for 64-bit clang-cl.
796 static void TranslateDArg(Arg *A, llvm::opt::DerivedArgList &DAL,
797 const OptTable &Opts) {
798 assert(A->getOption().matches(options::OPT_D));
800 StringRef Val = A->getValue();
801 size_t Hash = Val.find('#');
802 if (Hash == StringRef::npos || Hash > Val.find('=')) {
807 std::string NewVal = Val;
809 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_D), NewVal);
812 llvm::opt::DerivedArgList *
813 MSVCToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args,
814 const char *BoundArch) const {
815 DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
816 const OptTable &Opts = getDriver().getOpts();
818 // /Oy and /Oy- only has an effect under X86-32.
819 bool SupportsForcingFramePointer = getArch() == llvm::Triple::x86;
821 // The -O[12xd] flag actually expands to several flags. We must desugar the
822 // flags so that options embedded can be negated. For example, the '-O2' flag
823 // enables '-Oy'. Expanding '-O2' into its constituent flags allows us to
824 // correctly handle '-O2 -Oy-' where the trailing '-Oy-' disables a single
827 // Note that this expansion logic only applies to the *last* of '[12xd]'.
829 // First step is to search for the character we'd like to expand.
830 const char *ExpandChar = nullptr;
831 for (Arg *A : Args) {
832 if (!A->getOption().matches(options::OPT__SLASH_O))
834 StringRef OptStr = A->getValue();
835 for (size_t I = 0, E = OptStr.size(); I != E; ++I) {
836 char OptChar = OptStr[I];
837 char PrevChar = I > 0 ? OptStr[I - 1] : '0';
838 if (PrevChar == 'b') {
839 // OptChar does not expand; it's an argument to the previous char.
842 if (OptChar == '1' || OptChar == '2' || OptChar == 'x' || OptChar == 'd')
843 ExpandChar = OptStr.data() + I;
847 for (Arg *A : Args) {
848 if (A->getOption().matches(options::OPT__SLASH_O)) {
849 // The -O flag actually takes an amalgam of other options. For example,
850 // '/Ogyb2' is equivalent to '/Og' '/Oy' '/Ob2'.
851 TranslateOptArg(A, *DAL, SupportsForcingFramePointer, ExpandChar, Opts);
852 } else if (A->getOption().matches(options::OPT_D)) {
853 // Translate -Dfoo#bar into -Dfoo=bar.
854 TranslateDArg(A, *DAL, Opts);