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/Process.h"
28 // Include the necessary headers to interface with the Windows registry and
30 #if defined(LLVM_ON_WIN32)
35 #define WIN32_LEAN_AND_MEAN
43 using namespace clang::driver;
44 using namespace clang::driver::toolchains;
45 using namespace clang;
46 using namespace llvm::opt;
48 MSVCToolChain::MSVCToolChain(const Driver &D, const llvm::Triple& Triple,
50 : ToolChain(D, Triple, Args) {
51 getProgramPaths().push_back(getDriver().getInstalledDir());
52 if (getDriver().getInstalledDir() != getDriver().Dir)
53 getProgramPaths().push_back(getDriver().Dir);
56 Tool *MSVCToolChain::buildLinker() const {
57 return new tools::visualstudio::Linker(*this);
60 Tool *MSVCToolChain::buildAssembler() const {
61 if (getTriple().isOSBinFormatMachO())
62 return new tools::darwin::Assembler(*this);
63 getDriver().Diag(clang::diag::err_no_external_assembler);
67 bool MSVCToolChain::IsIntegratedAssemblerDefault() const {
71 bool MSVCToolChain::IsUnwindTablesDefault() const {
72 // Emit unwind tables by default on Win64. All non-x86_32 Windows platforms
73 // such as ARM and PPC actually require unwind tables, but LLVM doesn't know
74 // how to generate them yet.
76 // Don't emit unwind tables by default for MachO targets.
77 if (getTriple().isOSBinFormatMachO())
80 return getArch() == llvm::Triple::x86_64;
83 bool MSVCToolChain::isPICDefault() const {
84 return getArch() == llvm::Triple::x86_64;
87 bool MSVCToolChain::isPIEDefault() const {
91 bool MSVCToolChain::isPICDefaultForced() const {
92 return getArch() == llvm::Triple::x86_64;
96 static bool readFullStringValue(HKEY hkey, const char *valueName,
98 // FIXME: We should be using the W versions of the registry functions, but
99 // doing so requires UTF8 / UTF16 conversions similar to how we handle command
100 // line arguments. The UTF8 conversion functions are not exposed publicly
101 // from LLVM though, so in order to do this we will probably need to create
102 // a registry abstraction in LLVMSupport that is Windows only.
106 // First just query for the required size.
107 result = RegQueryValueEx(hkey, valueName, NULL, &type, NULL, &valueSize);
108 if (result != ERROR_SUCCESS || type != REG_SZ)
110 std::vector<BYTE> buffer(valueSize);
111 result = RegQueryValueEx(hkey, valueName, NULL, NULL, &buffer[0], &valueSize);
112 if (result == ERROR_SUCCESS)
113 value.assign(reinterpret_cast<const char *>(buffer.data()));
118 /// \brief Read registry string.
119 /// This also supports a means to look for high-versioned keys by use
120 /// of a $VERSION placeholder in the key path.
121 /// $VERSION in the key path is a placeholder for the version number,
122 /// causing the highest value path to be searched for and used.
123 /// I.e. "SOFTWARE\\Microsoft\\VisualStudio\\$VERSION".
124 /// There can be additional characters in the component. Only the numeric
125 /// characters are compared. This function only searches HKLM.
126 static bool getSystemRegistryString(const char *keyPath, const char *valueName,
127 std::string &value, std::string *phValue) {
131 HKEY hRootKey = HKEY_LOCAL_MACHINE;
134 bool returnValue = false;
136 const char *placeHolder = strstr(keyPath, "$VERSION");
137 std::string bestName;
138 // If we have a $VERSION placeholder, do the highest-version search.
140 const char *keyEnd = placeHolder - 1;
141 const char *nextKey = placeHolder;
142 // Find end of previous key.
143 while ((keyEnd > keyPath) && (*keyEnd != '\\'))
145 // Find end of key containing $VERSION.
146 while (*nextKey && (*nextKey != '\\'))
148 size_t partialKeyLength = keyEnd - keyPath;
149 char partialKey[256];
150 if (partialKeyLength >= sizeof(partialKey))
151 partialKeyLength = sizeof(partialKey) - 1;
152 strncpy(partialKey, keyPath, partialKeyLength);
153 partialKey[partialKeyLength] = '\0';
155 lResult = RegOpenKeyEx(hRootKey, partialKey, 0, KEY_READ | KEY_WOW64_32KEY,
157 if (lResult == ERROR_SUCCESS) {
159 double bestValue = 0.0;
160 DWORD index, size = sizeof(keyName) - 1;
161 for (index = 0; RegEnumKeyEx(hTopKey, index, keyName, &size, NULL,
162 NULL, NULL, NULL) == ERROR_SUCCESS; index++) {
163 const char *sp = keyName;
164 while (*sp && !isDigit(*sp))
168 const char *ep = sp + 1;
169 while (*ep && (isDigit(*ep) || (*ep == '.')))
172 strncpy(numBuf, sp, sizeof(numBuf) - 1);
173 numBuf[sizeof(numBuf) - 1] = '\0';
174 double dvalue = strtod(numBuf, NULL);
175 if (dvalue > bestValue) {
176 // Test that InstallDir is indeed there before keeping this index.
177 // Open the chosen key path remainder.
179 // Append rest of key.
180 bestName.append(nextKey);
181 lResult = RegOpenKeyEx(hTopKey, bestName.c_str(), 0,
182 KEY_READ | KEY_WOW64_32KEY, &hKey);
183 if (lResult == ERROR_SUCCESS) {
184 lResult = readFullStringValue(hKey, valueName, value);
185 if (lResult == ERROR_SUCCESS) {
194 size = sizeof(keyName) - 1;
196 RegCloseKey(hTopKey);
200 RegOpenKeyEx(hRootKey, keyPath, 0, KEY_READ | KEY_WOW64_32KEY, &hKey);
201 if (lResult == ERROR_SUCCESS) {
202 lResult = readFullStringValue(hKey, valueName, value);
203 if (lResult == ERROR_SUCCESS)
214 // Convert LLVM's ArchType
215 // to the corresponding name of Windows SDK libraries subfolder
216 static StringRef getWindowsSDKArch(llvm::Triple::ArchType Arch) {
218 case llvm::Triple::x86:
220 case llvm::Triple::x86_64:
222 case llvm::Triple::arm:
229 // Find the most recent version of Universal CRT or Windows 10 SDK.
230 // vcvarsqueryregistry.bat from Visual Studio 2015 sorts entries in the include
231 // directory by name and uses the last one of the list.
232 // So we compare entry names lexicographically to find the greatest one.
233 static bool getWindows10SDKVersion(const std::string &SDKPath,
234 std::string &SDKVersion) {
238 llvm::SmallString<128> IncludePath(SDKPath);
239 llvm::sys::path::append(IncludePath, "Include");
240 for (llvm::sys::fs::directory_iterator DirIt(IncludePath, EC), DirEnd;
241 DirIt != DirEnd && !EC; DirIt.increment(EC)) {
242 if (!llvm::sys::fs::is_directory(DirIt->path()))
244 StringRef CandidateName = llvm::sys::path::filename(DirIt->path());
245 // If WDK is installed, there could be subfolders like "wdf" in the
246 // "Include" directory.
247 // Allow only directories which names start with "10.".
248 if (!CandidateName.startswith("10."))
250 if (CandidateName > SDKVersion)
251 SDKVersion = CandidateName;
254 return !SDKVersion.empty();
257 /// \brief Get Windows SDK installation directory.
258 bool MSVCToolChain::getWindowsSDKDir(std::string &Path, int &Major,
259 std::string &WindowsSDKIncludeVersion,
260 std::string &WindowsSDKLibVersion) const {
261 std::string RegistrySDKVersion;
262 // Try the Windows registry.
263 if (!getSystemRegistryString(
264 "SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\$VERSION",
265 "InstallationFolder", Path, &RegistrySDKVersion))
267 if (Path.empty() || RegistrySDKVersion.empty())
270 WindowsSDKIncludeVersion.clear();
271 WindowsSDKLibVersion.clear();
273 std::sscanf(RegistrySDKVersion.c_str(), "v%d.", &Major);
277 // Windows SDK 8.x installs libraries in a folder whose names depend on the
278 // version of the OS you're targeting. By default choose the newest, which
279 // usually corresponds to the version of the OS you've installed the SDK on.
280 const char *Tests[] = {"winv6.3", "win8", "win7"};
281 for (const char *Test : Tests) {
282 llvm::SmallString<128> TestPath(Path);
283 llvm::sys::path::append(TestPath, "Lib", Test);
284 if (llvm::sys::fs::exists(TestPath.c_str())) {
285 WindowsSDKLibVersion = Test;
289 return !WindowsSDKLibVersion.empty();
292 if (!getWindows10SDKVersion(Path, WindowsSDKIncludeVersion))
294 WindowsSDKLibVersion = WindowsSDKIncludeVersion;
297 // Unsupported SDK version
301 // Gets the library path required to link against the Windows SDK.
302 bool MSVCToolChain::getWindowsSDKLibraryPath(std::string &path) const {
305 std::string windowsSDKIncludeVersion;
306 std::string windowsSDKLibVersion;
309 if (!getWindowsSDKDir(sdkPath, sdkMajor, windowsSDKIncludeVersion,
310 windowsSDKLibVersion))
313 llvm::SmallString<128> libPath(sdkPath);
314 llvm::sys::path::append(libPath, "Lib");
317 // In Windows SDK 7.x, x86 libraries are directly in the Lib folder.
318 case llvm::Triple::x86:
320 case llvm::Triple::x86_64:
321 llvm::sys::path::append(libPath, "x64");
323 case llvm::Triple::arm:
324 // It is not necessary to link against Windows SDK 7.x when targeting ARM.
330 const StringRef archName = getWindowsSDKArch(getArch());
331 if (archName.empty())
333 llvm::sys::path::append(libPath, windowsSDKLibVersion, "um", archName);
336 path = libPath.str();
340 // Check if the Include path of a specified version of Visual Studio contains
341 // specific header files. If not, they are probably shipped with Universal CRT.
342 bool clang::driver::toolchains::MSVCToolChain::useUniversalCRT(
343 std::string &VisualStudioDir) const {
344 llvm::SmallString<128> TestPath(VisualStudioDir);
345 llvm::sys::path::append(TestPath, "VC\\include\\stdlib.h");
347 return !llvm::sys::fs::exists(TestPath);
350 bool MSVCToolChain::getUniversalCRTSdkDir(std::string &Path,
351 std::string &UCRTVersion) const {
352 // vcvarsqueryregistry.bat for Visual Studio 2015 queries the registry
353 // for the specific key "KitsRoot10". So do we.
354 if (!getSystemRegistryString(
355 "SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots", "KitsRoot10",
359 return getWindows10SDKVersion(Path, UCRTVersion);
362 bool MSVCToolChain::getUniversalCRTLibraryPath(std::string &Path) const {
363 std::string UniversalCRTSdkPath;
364 std::string UCRTVersion;
367 if (!getUniversalCRTSdkDir(UniversalCRTSdkPath, UCRTVersion))
370 StringRef ArchName = getWindowsSDKArch(getArch());
371 if (ArchName.empty())
374 llvm::SmallString<128> LibPath(UniversalCRTSdkPath);
375 llvm::sys::path::append(LibPath, "Lib", UCRTVersion, "ucrt", ArchName);
377 Path = LibPath.str();
381 // Get the location to use for Visual Studio binaries. The location priority
382 // is: %VCINSTALLDIR% > %PATH% > newest copy of Visual Studio installed on
383 // system (as reported by the registry).
384 bool MSVCToolChain::getVisualStudioBinariesFolder(const char *clangProgramPath,
385 std::string &path) const {
388 SmallString<128> BinDir;
390 // First check the environment variables that vsvars32.bat sets.
391 llvm::Optional<std::string> VcInstallDir =
392 llvm::sys::Process::GetEnv("VCINSTALLDIR");
393 if (VcInstallDir.hasValue()) {
394 BinDir = VcInstallDir.getValue();
395 llvm::sys::path::append(BinDir, "bin");
397 // Next walk the PATH, trying to find a cl.exe in the path. If we find one,
398 // use that. However, make sure it's not clang's cl.exe.
399 llvm::Optional<std::string> OptPath = llvm::sys::Process::GetEnv("PATH");
400 if (OptPath.hasValue()) {
401 const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'};
402 SmallVector<StringRef, 8> PathSegments;
403 llvm::SplitString(OptPath.getValue(), PathSegments, EnvPathSeparatorStr);
405 for (StringRef PathSegment : PathSegments) {
406 if (PathSegment.empty())
409 SmallString<128> FilePath(PathSegment);
410 llvm::sys::path::append(FilePath, "cl.exe");
411 // Checking if cl.exe exists is a small optimization over calling
412 // can_execute, which really only checks for existence but will also do
413 // extra checks for cl.exe.exe. These add up when walking a long path.
414 if (llvm::sys::fs::exists(FilePath.c_str()) &&
415 !llvm::sys::fs::equivalent(FilePath.c_str(), clangProgramPath)) {
416 // If we found it on the PATH, use it exactly as is with no
424 std::string installDir;
425 // With no VCINSTALLDIR and nothing on the PATH, if we can't find it in the
426 // registry then we have no choice but to fail.
427 if (!getVisualStudioInstallDir(installDir))
430 // Regardless of what binary we're ultimately trying to find, we make sure
431 // that this is a Visual Studio directory by checking for cl.exe. We use
432 // cl.exe instead of other binaries like link.exe because programs such as
433 // GnuWin32 also have a utility called link.exe, so cl.exe is the least
436 llvm::sys::path::append(BinDir, "VC", "bin");
437 SmallString<128> ClPath(BinDir);
438 llvm::sys::path::append(ClPath, "cl.exe");
440 if (!llvm::sys::fs::can_execute(ClPath.c_str()))
448 case llvm::Triple::x86:
450 case llvm::Triple::x86_64:
451 llvm::sys::path::append(BinDir, "amd64");
453 case llvm::Triple::arm:
454 llvm::sys::path::append(BinDir, "arm");
457 // Whatever this is, Visual Studio doesn't have a toolchain for it.
464 VersionTuple MSVCToolChain::getMSVCVersionFromExe() const {
465 VersionTuple Version;
468 if (!getVisualStudioBinariesFolder("", BinPath))
470 SmallString<128> ClExe(BinPath);
471 llvm::sys::path::append(ClExe, "cl.exe");
473 std::wstring ClExeWide;
474 if (!llvm::ConvertUTF8toWide(ClExe.c_str(), ClExeWide))
477 const DWORD VersionSize = ::GetFileVersionInfoSizeW(ClExeWide.c_str(),
479 if (VersionSize == 0)
482 SmallVector<uint8_t, 4 * 1024> VersionBlock(VersionSize);
483 if (!::GetFileVersionInfoW(ClExeWide.c_str(), 0, VersionSize,
484 VersionBlock.data()))
487 VS_FIXEDFILEINFO *FileInfo = nullptr;
488 UINT FileInfoSize = 0;
489 if (!::VerQueryValueW(VersionBlock.data(), L"\\",
490 reinterpret_cast<LPVOID *>(&FileInfo), &FileInfoSize) ||
491 FileInfoSize < sizeof(*FileInfo))
494 const unsigned Major = (FileInfo->dwFileVersionMS >> 16) & 0xFFFF;
495 const unsigned Minor = (FileInfo->dwFileVersionMS ) & 0xFFFF;
496 const unsigned Micro = (FileInfo->dwFileVersionLS >> 16) & 0xFFFF;
498 Version = VersionTuple(Major, Minor, Micro);
503 // Get Visual Studio installation directory.
504 bool MSVCToolChain::getVisualStudioInstallDir(std::string &path) const {
505 // First check the environment variables that vsvars32.bat sets.
506 const char *vcinstalldir = getenv("VCINSTALLDIR");
509 path = path.substr(0, path.find("\\VC"));
513 std::string vsIDEInstallDir;
514 std::string vsExpressIDEInstallDir;
515 // Then try the windows registry.
517 getSystemRegistryString("SOFTWARE\\Microsoft\\VisualStudio\\$VERSION",
518 "InstallDir", vsIDEInstallDir, nullptr);
519 if (hasVCDir && !vsIDEInstallDir.empty()) {
520 path = vsIDEInstallDir.substr(0, vsIDEInstallDir.find("\\Common7\\IDE"));
524 bool hasVCExpressDir =
525 getSystemRegistryString("SOFTWARE\\Microsoft\\VCExpress\\$VERSION",
526 "InstallDir", vsExpressIDEInstallDir, nullptr);
527 if (hasVCExpressDir && !vsExpressIDEInstallDir.empty()) {
528 path = vsExpressIDEInstallDir.substr(
529 0, vsIDEInstallDir.find("\\Common7\\IDE"));
533 // Try the environment.
534 const char *vs120comntools = getenv("VS120COMNTOOLS");
535 const char *vs100comntools = getenv("VS100COMNTOOLS");
536 const char *vs90comntools = getenv("VS90COMNTOOLS");
537 const char *vs80comntools = getenv("VS80COMNTOOLS");
539 const char *vscomntools = nullptr;
541 // Find any version we can
543 vscomntools = vs120comntools;
544 else if (vs100comntools)
545 vscomntools = vs100comntools;
546 else if (vs90comntools)
547 vscomntools = vs90comntools;
548 else if (vs80comntools)
549 vscomntools = vs80comntools;
551 if (vscomntools && *vscomntools) {
552 const char *p = strstr(vscomntools, "\\Common7\\Tools");
553 path = p ? std::string(vscomntools, p) : vscomntools;
559 void MSVCToolChain::AddSystemIncludeWithSubfolder(
560 const ArgList &DriverArgs, ArgStringList &CC1Args,
561 const std::string &folder, const Twine &subfolder1, const Twine &subfolder2,
562 const Twine &subfolder3) const {
563 llvm::SmallString<128> path(folder);
564 llvm::sys::path::append(path, subfolder1, subfolder2, subfolder3);
565 addSystemInclude(DriverArgs, CC1Args, path);
568 void MSVCToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
569 ArgStringList &CC1Args) const {
570 if (DriverArgs.hasArg(options::OPT_nostdinc))
573 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
574 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, getDriver().ResourceDir,
578 // Add %INCLUDE%-like directories from the -imsvc flag.
579 for (const auto &Path : DriverArgs.getAllArgValues(options::OPT__SLASH_imsvc))
580 addSystemInclude(DriverArgs, CC1Args, Path);
582 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
585 // Honor %INCLUDE%. It should know essential search paths with vcvarsall.bat.
586 if (const char *cl_include_dir = getenv("INCLUDE")) {
587 SmallVector<StringRef, 8> Dirs;
588 StringRef(cl_include_dir)
589 .split(Dirs, ";", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
590 for (StringRef Dir : Dirs)
591 addSystemInclude(DriverArgs, CC1Args, Dir);
598 // When built with access to the proper Windows APIs, try to actually find
599 // the correct include paths first.
600 if (getVisualStudioInstallDir(VSDir)) {
601 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, VSDir, "VC\\include");
603 if (useUniversalCRT(VSDir)) {
604 std::string UniversalCRTSdkPath;
605 std::string UCRTVersion;
606 if (getUniversalCRTSdkDir(UniversalCRTSdkPath, UCRTVersion)) {
607 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, UniversalCRTSdkPath,
608 "Include", UCRTVersion, "ucrt");
612 std::string WindowsSDKDir;
614 std::string windowsSDKIncludeVersion;
615 std::string windowsSDKLibVersion;
616 if (getWindowsSDKDir(WindowsSDKDir, major, windowsSDKIncludeVersion,
617 windowsSDKLibVersion)) {
619 // Note: windowsSDKIncludeVersion is empty for SDKs prior to v10.
620 // Anyway, llvm::sys::path::append is able to manage it.
621 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
622 "include", windowsSDKIncludeVersion,
624 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
625 "include", windowsSDKIncludeVersion,
627 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
628 "include", windowsSDKIncludeVersion,
631 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
635 addSystemInclude(DriverArgs, CC1Args, VSDir);
640 // As a fallback, select default install paths.
641 // FIXME: Don't guess drives and paths like this on Windows.
642 const StringRef Paths[] = {
643 "C:/Program Files/Microsoft Visual Studio 10.0/VC/include",
644 "C:/Program Files/Microsoft Visual Studio 9.0/VC/include",
645 "C:/Program Files/Microsoft Visual Studio 9.0/VC/PlatformSDK/Include",
646 "C:/Program Files/Microsoft Visual Studio 8/VC/include",
647 "C:/Program Files/Microsoft Visual Studio 8/VC/PlatformSDK/Include"
649 addSystemIncludes(DriverArgs, CC1Args, Paths);
652 void MSVCToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
653 ArgStringList &CC1Args) const {
654 // FIXME: There should probably be logic here to find libc++ on Windows.
658 MSVCToolChain::ComputeEffectiveClangTriple(const ArgList &Args,
659 types::ID InputType) const {
660 std::string TripleStr =
661 ToolChain::ComputeEffectiveClangTriple(Args, InputType);
662 llvm::Triple Triple(TripleStr);
664 tools::visualstudio::getMSVCVersion(/*D=*/nullptr, *this, Triple, Args,
665 /*IsWindowsMSVC=*/true);
669 MSVT = VersionTuple(MSVT.getMajor(), MSVT.getMinor().getValueOr(0),
670 MSVT.getSubminor().getValueOr(0));
672 if (Triple.getEnvironment() == llvm::Triple::MSVC) {
673 StringRef ObjFmt = Triple.getEnvironmentName().split('-').second;
675 Triple.setEnvironmentName((Twine("msvc") + MSVT.getAsString()).str());
677 Triple.setEnvironmentName(
678 (Twine("msvc") + MSVT.getAsString() + Twine('-') + ObjFmt).str());
680 return Triple.getTriple();
683 SanitizerMask MSVCToolChain::getSupportedSanitizers() const {
684 SanitizerMask Res = ToolChain::getSupportedSanitizers();
685 Res |= SanitizerKind::Address;
689 static void TranslateOptArg(Arg *A, llvm::opt::DerivedArgList &DAL,
690 bool SupportsForcingFramePointer,
691 const char *ExpandChar, const OptTable &Opts) {
692 assert(A->getOption().matches(options::OPT__SLASH_O));
694 StringRef OptStr = A->getValue();
695 for (size_t I = 0, E = OptStr.size(); I != E; ++I) {
696 const char &OptChar = *(OptStr.data() + I);
704 if (&OptChar == ExpandChar) {
705 if (OptChar == 'd') {
706 DAL.AddFlagArg(A, Opts.getOption(options::OPT_O0));
708 if (OptChar == '1') {
709 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "s");
710 } else if (OptChar == '2' || OptChar == 'x') {
711 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
712 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "2");
714 if (SupportsForcingFramePointer &&
715 !DAL.hasArgNoClaim(options::OPT_fno_omit_frame_pointer))
717 Opts.getOption(options::OPT_fomit_frame_pointer));
718 if (OptChar == '1' || OptChar == '2')
720 Opts.getOption(options::OPT_ffunction_sections));
725 if (I + 1 != E && isdigit(OptStr[I + 1])) {
726 switch (OptStr[I + 1]) {
728 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_inline));
731 // TODO: Inline calls to 'inline functions' only.
734 DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_functions));
743 if (I + 1 != E && OptStr[I + 1] == '-') {
745 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_builtin));
747 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
751 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "s");
754 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "2");
757 bool OmitFramePointer = true;
758 if (I + 1 != E && OptStr[I + 1] == '-') {
759 OmitFramePointer = false;
762 if (SupportsForcingFramePointer) {
763 if (OmitFramePointer)
765 Opts.getOption(options::OPT_fomit_frame_pointer));
768 A, Opts.getOption(options::OPT_fno_omit_frame_pointer));
770 // Don't warn about /Oy- in 64-bit builds (where
771 // SupportsForcingFramePointer is false). The flag having no effect
772 // there is a compiler-internal optimization, and people shouldn't have
773 // to special-case their build files for 64-bit clang-cl.
782 static void TranslateDArg(Arg *A, llvm::opt::DerivedArgList &DAL,
783 const OptTable &Opts) {
784 assert(A->getOption().matches(options::OPT_D));
786 StringRef Val = A->getValue();
787 size_t Hash = Val.find('#');
788 if (Hash == StringRef::npos || Hash > Val.find('=')) {
793 std::string NewVal = Val;
795 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_D), NewVal);
798 llvm::opt::DerivedArgList *
799 MSVCToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args,
800 const char *BoundArch) const {
801 DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
802 const OptTable &Opts = getDriver().getOpts();
804 // /Oy and /Oy- only has an effect under X86-32.
805 bool SupportsForcingFramePointer = getArch() == llvm::Triple::x86;
807 // The -O[12xd] flag actually expands to several flags. We must desugar the
808 // flags so that options embedded can be negated. For example, the '-O2' flag
809 // enables '-Oy'. Expanding '-O2' into its constituent flags allows us to
810 // correctly handle '-O2 -Oy-' where the trailing '-Oy-' disables a single
813 // Note that this expansion logic only applies to the *last* of '[12xd]'.
815 // First step is to search for the character we'd like to expand.
816 const char *ExpandChar = nullptr;
817 for (Arg *A : Args) {
818 if (!A->getOption().matches(options::OPT__SLASH_O))
820 StringRef OptStr = A->getValue();
821 for (size_t I = 0, E = OptStr.size(); I != E; ++I) {
822 char OptChar = OptStr[I];
823 char PrevChar = I > 0 ? OptStr[I - 1] : '0';
824 if (PrevChar == 'b') {
825 // OptChar does not expand; it's an argument to the previous char.
828 if (OptChar == '1' || OptChar == '2' || OptChar == 'x' || OptChar == 'd')
829 ExpandChar = OptStr.data() + I;
833 for (Arg *A : Args) {
834 if (A->getOption().matches(options::OPT__SLASH_O)) {
835 // The -O flag actually takes an amalgam of other options. For example,
836 // '/Ogyb2' is equivalent to '/Og' '/Oy' '/Ob2'.
837 TranslateOptArg(A, *DAL, SupportsForcingFramePointer, ExpandChar, Opts);
838 } else if (A->getOption().matches(options::OPT_D)) {
839 // Translate -Dfoo#bar into -Dfoo=bar.
840 TranslateDArg(A, *DAL, Opts);