xref: /aosp_15_r20/external/clang/lib/Driver/MSVCToolChain.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li //===--- ToolChains.cpp - ToolChain Implementations -----------------------===//
2*67e74705SXin Li //
3*67e74705SXin Li //                     The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===----------------------------------------------------------------------===//
9*67e74705SXin Li 
10*67e74705SXin Li #include "ToolChains.h"
11*67e74705SXin Li #include "Tools.h"
12*67e74705SXin Li #include "clang/Basic/CharInfo.h"
13*67e74705SXin Li #include "clang/Basic/Version.h"
14*67e74705SXin Li #include "clang/Driver/Compilation.h"
15*67e74705SXin Li #include "clang/Driver/Driver.h"
16*67e74705SXin Li #include "clang/Driver/DriverDiagnostic.h"
17*67e74705SXin Li #include "clang/Driver/Options.h"
18*67e74705SXin Li #include "llvm/ADT/StringExtras.h"
19*67e74705SXin Li #include "llvm/Config/llvm-config.h"
20*67e74705SXin Li #include "llvm/Option/Arg.h"
21*67e74705SXin Li #include "llvm/Option/ArgList.h"
22*67e74705SXin Li #include "llvm/Support/ConvertUTF.h"
23*67e74705SXin Li #include "llvm/Support/ErrorHandling.h"
24*67e74705SXin Li #include "llvm/Support/FileSystem.h"
25*67e74705SXin Li #include "llvm/Support/Process.h"
26*67e74705SXin Li #include <cstdio>
27*67e74705SXin Li 
28*67e74705SXin Li // Include the necessary headers to interface with the Windows registry and
29*67e74705SXin Li // environment.
30*67e74705SXin Li #if defined(LLVM_ON_WIN32)
31*67e74705SXin Li #define USE_WIN32
32*67e74705SXin Li #endif
33*67e74705SXin Li 
34*67e74705SXin Li #ifdef USE_WIN32
35*67e74705SXin Li   #define WIN32_LEAN_AND_MEAN
36*67e74705SXin Li   #define NOGDI
37*67e74705SXin Li   #ifndef NOMINMAX
38*67e74705SXin Li     #define NOMINMAX
39*67e74705SXin Li   #endif
40*67e74705SXin Li   #include <windows.h>
41*67e74705SXin Li #endif
42*67e74705SXin Li 
43*67e74705SXin Li using namespace clang::driver;
44*67e74705SXin Li using namespace clang::driver::toolchains;
45*67e74705SXin Li using namespace clang;
46*67e74705SXin Li using namespace llvm::opt;
47*67e74705SXin Li 
MSVCToolChain(const Driver & D,const llvm::Triple & Triple,const ArgList & Args)48*67e74705SXin Li MSVCToolChain::MSVCToolChain(const Driver &D, const llvm::Triple& Triple,
49*67e74705SXin Li                              const ArgList &Args)
50*67e74705SXin Li   : ToolChain(D, Triple, Args) {
51*67e74705SXin Li   getProgramPaths().push_back(getDriver().getInstalledDir());
52*67e74705SXin Li   if (getDriver().getInstalledDir() != getDriver().Dir)
53*67e74705SXin Li     getProgramPaths().push_back(getDriver().Dir);
54*67e74705SXin Li }
55*67e74705SXin Li 
buildLinker() const56*67e74705SXin Li Tool *MSVCToolChain::buildLinker() const {
57*67e74705SXin Li   return new tools::visualstudio::Linker(*this);
58*67e74705SXin Li }
59*67e74705SXin Li 
buildAssembler() const60*67e74705SXin Li Tool *MSVCToolChain::buildAssembler() const {
61*67e74705SXin Li   if (getTriple().isOSBinFormatMachO())
62*67e74705SXin Li     return new tools::darwin::Assembler(*this);
63*67e74705SXin Li   getDriver().Diag(clang::diag::err_no_external_assembler);
64*67e74705SXin Li   return nullptr;
65*67e74705SXin Li }
66*67e74705SXin Li 
IsIntegratedAssemblerDefault() const67*67e74705SXin Li bool MSVCToolChain::IsIntegratedAssemblerDefault() const {
68*67e74705SXin Li   return true;
69*67e74705SXin Li }
70*67e74705SXin Li 
IsUnwindTablesDefault() const71*67e74705SXin Li bool MSVCToolChain::IsUnwindTablesDefault() const {
72*67e74705SXin Li   // Emit unwind tables by default on Win64. All non-x86_32 Windows platforms
73*67e74705SXin Li   // such as ARM and PPC actually require unwind tables, but LLVM doesn't know
74*67e74705SXin Li   // how to generate them yet.
75*67e74705SXin Li 
76*67e74705SXin Li   // Don't emit unwind tables by default for MachO targets.
77*67e74705SXin Li   if (getTriple().isOSBinFormatMachO())
78*67e74705SXin Li     return false;
79*67e74705SXin Li 
80*67e74705SXin Li   return getArch() == llvm::Triple::x86_64;
81*67e74705SXin Li }
82*67e74705SXin Li 
isPICDefault() const83*67e74705SXin Li bool MSVCToolChain::isPICDefault() const {
84*67e74705SXin Li   return getArch() == llvm::Triple::x86_64;
85*67e74705SXin Li }
86*67e74705SXin Li 
isPIEDefault() const87*67e74705SXin Li bool MSVCToolChain::isPIEDefault() const {
88*67e74705SXin Li   return false;
89*67e74705SXin Li }
90*67e74705SXin Li 
isPICDefaultForced() const91*67e74705SXin Li bool MSVCToolChain::isPICDefaultForced() const {
92*67e74705SXin Li   return getArch() == llvm::Triple::x86_64;
93*67e74705SXin Li }
94*67e74705SXin Li 
95*67e74705SXin Li #ifdef USE_WIN32
readFullStringValue(HKEY hkey,const char * valueName,std::string & value)96*67e74705SXin Li static bool readFullStringValue(HKEY hkey, const char *valueName,
97*67e74705SXin Li                                 std::string &value) {
98*67e74705SXin Li   std::wstring WideValueName;
99*67e74705SXin Li   if (!llvm::ConvertUTF8toWide(valueName, WideValueName))
100*67e74705SXin Li     return false;
101*67e74705SXin Li 
102*67e74705SXin Li   DWORD result = 0;
103*67e74705SXin Li   DWORD valueSize = 0;
104*67e74705SXin Li   DWORD type = 0;
105*67e74705SXin Li   // First just query for the required size.
106*67e74705SXin Li   result = RegQueryValueExW(hkey, WideValueName.c_str(), NULL, &type, NULL,
107*67e74705SXin Li                             &valueSize);
108*67e74705SXin Li   if (result != ERROR_SUCCESS || type != REG_SZ || !valueSize)
109*67e74705SXin Li     return false;
110*67e74705SXin Li   std::vector<BYTE> buffer(valueSize);
111*67e74705SXin Li   result = RegQueryValueExW(hkey, WideValueName.c_str(), NULL, NULL, &buffer[0],
112*67e74705SXin Li                             &valueSize);
113*67e74705SXin Li   if (result == ERROR_SUCCESS) {
114*67e74705SXin Li     std::wstring WideValue(reinterpret_cast<const wchar_t *>(buffer.data()),
115*67e74705SXin Li                            valueSize / sizeof(wchar_t));
116*67e74705SXin Li     // The destination buffer must be empty as an invariant of the conversion
117*67e74705SXin Li     // function; but this function is sometimes called in a loop that passes in
118*67e74705SXin Li     // the same buffer, however. Simply clear it out so we can overwrite it.
119*67e74705SXin Li     value.clear();
120*67e74705SXin Li     return llvm::convertWideToUTF8(WideValue, value);
121*67e74705SXin Li   }
122*67e74705SXin Li   return false;
123*67e74705SXin Li }
124*67e74705SXin Li #endif
125*67e74705SXin Li 
126*67e74705SXin Li /// \brief Read registry string.
127*67e74705SXin Li /// This also supports a means to look for high-versioned keys by use
128*67e74705SXin Li /// of a $VERSION placeholder in the key path.
129*67e74705SXin Li /// $VERSION in the key path is a placeholder for the version number,
130*67e74705SXin Li /// causing the highest value path to be searched for and used.
131*67e74705SXin Li /// I.e. "SOFTWARE\\Microsoft\\VisualStudio\\$VERSION".
132*67e74705SXin Li /// There can be additional characters in the component.  Only the numeric
133*67e74705SXin Li /// characters are compared.  This function only searches HKLM.
getSystemRegistryString(const char * keyPath,const char * valueName,std::string & value,std::string * phValue)134*67e74705SXin Li static bool getSystemRegistryString(const char *keyPath, const char *valueName,
135*67e74705SXin Li                                     std::string &value, std::string *phValue) {
136*67e74705SXin Li #ifndef USE_WIN32
137*67e74705SXin Li   return false;
138*67e74705SXin Li #else
139*67e74705SXin Li   HKEY hRootKey = HKEY_LOCAL_MACHINE;
140*67e74705SXin Li   HKEY hKey = NULL;
141*67e74705SXin Li   long lResult;
142*67e74705SXin Li   bool returnValue = false;
143*67e74705SXin Li 
144*67e74705SXin Li   const char *placeHolder = strstr(keyPath, "$VERSION");
145*67e74705SXin Li   std::string bestName;
146*67e74705SXin Li   // If we have a $VERSION placeholder, do the highest-version search.
147*67e74705SXin Li   if (placeHolder) {
148*67e74705SXin Li     const char *keyEnd = placeHolder - 1;
149*67e74705SXin Li     const char *nextKey = placeHolder;
150*67e74705SXin Li     // Find end of previous key.
151*67e74705SXin Li     while ((keyEnd > keyPath) && (*keyEnd != '\\'))
152*67e74705SXin Li       keyEnd--;
153*67e74705SXin Li     // Find end of key containing $VERSION.
154*67e74705SXin Li     while (*nextKey && (*nextKey != '\\'))
155*67e74705SXin Li       nextKey++;
156*67e74705SXin Li     size_t partialKeyLength = keyEnd - keyPath;
157*67e74705SXin Li     char partialKey[256];
158*67e74705SXin Li     if (partialKeyLength >= sizeof(partialKey))
159*67e74705SXin Li       partialKeyLength = sizeof(partialKey) - 1;
160*67e74705SXin Li     strncpy(partialKey, keyPath, partialKeyLength);
161*67e74705SXin Li     partialKey[partialKeyLength] = '\0';
162*67e74705SXin Li     HKEY hTopKey = NULL;
163*67e74705SXin Li     lResult = RegOpenKeyExA(hRootKey, partialKey, 0, KEY_READ | KEY_WOW64_32KEY,
164*67e74705SXin Li                             &hTopKey);
165*67e74705SXin Li     if (lResult == ERROR_SUCCESS) {
166*67e74705SXin Li       char keyName[256];
167*67e74705SXin Li       double bestValue = 0.0;
168*67e74705SXin Li       DWORD index, size = sizeof(keyName) - 1;
169*67e74705SXin Li       for (index = 0; RegEnumKeyExA(hTopKey, index, keyName, &size, NULL, NULL,
170*67e74705SXin Li                                     NULL, NULL) == ERROR_SUCCESS;
171*67e74705SXin Li            index++) {
172*67e74705SXin Li         const char *sp = keyName;
173*67e74705SXin Li         while (*sp && !isDigit(*sp))
174*67e74705SXin Li           sp++;
175*67e74705SXin Li         if (!*sp)
176*67e74705SXin Li           continue;
177*67e74705SXin Li         const char *ep = sp + 1;
178*67e74705SXin Li         while (*ep && (isDigit(*ep) || (*ep == '.')))
179*67e74705SXin Li           ep++;
180*67e74705SXin Li         char numBuf[32];
181*67e74705SXin Li         strncpy(numBuf, sp, sizeof(numBuf) - 1);
182*67e74705SXin Li         numBuf[sizeof(numBuf) - 1] = '\0';
183*67e74705SXin Li         double dvalue = strtod(numBuf, NULL);
184*67e74705SXin Li         if (dvalue > bestValue) {
185*67e74705SXin Li           // Test that InstallDir is indeed there before keeping this index.
186*67e74705SXin Li           // Open the chosen key path remainder.
187*67e74705SXin Li           bestName = keyName;
188*67e74705SXin Li           // Append rest of key.
189*67e74705SXin Li           bestName.append(nextKey);
190*67e74705SXin Li           lResult = RegOpenKeyExA(hTopKey, bestName.c_str(), 0,
191*67e74705SXin Li                                   KEY_READ | KEY_WOW64_32KEY, &hKey);
192*67e74705SXin Li           if (lResult == ERROR_SUCCESS) {
193*67e74705SXin Li             lResult = readFullStringValue(hKey, valueName, value);
194*67e74705SXin Li             if (lResult == ERROR_SUCCESS) {
195*67e74705SXin Li               bestValue = dvalue;
196*67e74705SXin Li               if (phValue)
197*67e74705SXin Li                 *phValue = bestName;
198*67e74705SXin Li               returnValue = true;
199*67e74705SXin Li             }
200*67e74705SXin Li             RegCloseKey(hKey);
201*67e74705SXin Li           }
202*67e74705SXin Li         }
203*67e74705SXin Li         size = sizeof(keyName) - 1;
204*67e74705SXin Li       }
205*67e74705SXin Li       RegCloseKey(hTopKey);
206*67e74705SXin Li     }
207*67e74705SXin Li   } else {
208*67e74705SXin Li     lResult =
209*67e74705SXin Li         RegOpenKeyExA(hRootKey, keyPath, 0, KEY_READ | KEY_WOW64_32KEY, &hKey);
210*67e74705SXin Li     if (lResult == ERROR_SUCCESS) {
211*67e74705SXin Li       lResult = readFullStringValue(hKey, valueName, value);
212*67e74705SXin Li       if (lResult == ERROR_SUCCESS)
213*67e74705SXin Li         returnValue = true;
214*67e74705SXin Li       if (phValue)
215*67e74705SXin Li         phValue->clear();
216*67e74705SXin Li       RegCloseKey(hKey);
217*67e74705SXin Li     }
218*67e74705SXin Li   }
219*67e74705SXin Li   return returnValue;
220*67e74705SXin Li #endif // USE_WIN32
221*67e74705SXin Li }
222*67e74705SXin Li 
223*67e74705SXin Li // Convert LLVM's ArchType
224*67e74705SXin Li // to the corresponding name of Windows SDK libraries subfolder
getWindowsSDKArch(llvm::Triple::ArchType Arch)225*67e74705SXin Li static StringRef getWindowsSDKArch(llvm::Triple::ArchType Arch) {
226*67e74705SXin Li   switch (Arch) {
227*67e74705SXin Li   case llvm::Triple::x86:
228*67e74705SXin Li     return "x86";
229*67e74705SXin Li   case llvm::Triple::x86_64:
230*67e74705SXin Li     return "x64";
231*67e74705SXin Li   case llvm::Triple::arm:
232*67e74705SXin Li     return "arm";
233*67e74705SXin Li   default:
234*67e74705SXin Li     return "";
235*67e74705SXin Li   }
236*67e74705SXin Li }
237*67e74705SXin Li 
238*67e74705SXin Li // Find the most recent version of Universal CRT or Windows 10 SDK.
239*67e74705SXin Li // vcvarsqueryregistry.bat from Visual Studio 2015 sorts entries in the include
240*67e74705SXin Li // directory by name and uses the last one of the list.
241*67e74705SXin Li // So we compare entry names lexicographically to find the greatest one.
getWindows10SDKVersion(const std::string & SDKPath,std::string & SDKVersion)242*67e74705SXin Li static bool getWindows10SDKVersion(const std::string &SDKPath,
243*67e74705SXin Li                                    std::string &SDKVersion) {
244*67e74705SXin Li   SDKVersion.clear();
245*67e74705SXin Li 
246*67e74705SXin Li   std::error_code EC;
247*67e74705SXin Li   llvm::SmallString<128> IncludePath(SDKPath);
248*67e74705SXin Li   llvm::sys::path::append(IncludePath, "Include");
249*67e74705SXin Li   for (llvm::sys::fs::directory_iterator DirIt(IncludePath, EC), DirEnd;
250*67e74705SXin Li        DirIt != DirEnd && !EC; DirIt.increment(EC)) {
251*67e74705SXin Li     if (!llvm::sys::fs::is_directory(DirIt->path()))
252*67e74705SXin Li       continue;
253*67e74705SXin Li     StringRef CandidateName = llvm::sys::path::filename(DirIt->path());
254*67e74705SXin Li     // If WDK is installed, there could be subfolders like "wdf" in the
255*67e74705SXin Li     // "Include" directory.
256*67e74705SXin Li     // Allow only directories which names start with "10.".
257*67e74705SXin Li     if (!CandidateName.startswith("10."))
258*67e74705SXin Li       continue;
259*67e74705SXin Li     if (CandidateName > SDKVersion)
260*67e74705SXin Li       SDKVersion = CandidateName;
261*67e74705SXin Li   }
262*67e74705SXin Li 
263*67e74705SXin Li   return !SDKVersion.empty();
264*67e74705SXin Li }
265*67e74705SXin Li 
266*67e74705SXin Li /// \brief Get Windows SDK installation directory.
getWindowsSDKDir(std::string & Path,int & Major,std::string & WindowsSDKIncludeVersion,std::string & WindowsSDKLibVersion) const267*67e74705SXin Li bool MSVCToolChain::getWindowsSDKDir(std::string &Path, int &Major,
268*67e74705SXin Li                                      std::string &WindowsSDKIncludeVersion,
269*67e74705SXin Li                                      std::string &WindowsSDKLibVersion) const {
270*67e74705SXin Li   std::string RegistrySDKVersion;
271*67e74705SXin Li   // Try the Windows registry.
272*67e74705SXin Li   if (!getSystemRegistryString(
273*67e74705SXin Li           "SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\$VERSION",
274*67e74705SXin Li           "InstallationFolder", Path, &RegistrySDKVersion))
275*67e74705SXin Li     return false;
276*67e74705SXin Li   if (Path.empty() || RegistrySDKVersion.empty())
277*67e74705SXin Li     return false;
278*67e74705SXin Li 
279*67e74705SXin Li   WindowsSDKIncludeVersion.clear();
280*67e74705SXin Li   WindowsSDKLibVersion.clear();
281*67e74705SXin Li   Major = 0;
282*67e74705SXin Li   std::sscanf(RegistrySDKVersion.c_str(), "v%d.", &Major);
283*67e74705SXin Li   if (Major <= 7)
284*67e74705SXin Li     return true;
285*67e74705SXin Li   if (Major == 8) {
286*67e74705SXin Li     // Windows SDK 8.x installs libraries in a folder whose names depend on the
287*67e74705SXin Li     // version of the OS you're targeting.  By default choose the newest, which
288*67e74705SXin Li     // usually corresponds to the version of the OS you've installed the SDK on.
289*67e74705SXin Li     const char *Tests[] = {"winv6.3", "win8", "win7"};
290*67e74705SXin Li     for (const char *Test : Tests) {
291*67e74705SXin Li       llvm::SmallString<128> TestPath(Path);
292*67e74705SXin Li       llvm::sys::path::append(TestPath, "Lib", Test);
293*67e74705SXin Li       if (llvm::sys::fs::exists(TestPath.c_str())) {
294*67e74705SXin Li         WindowsSDKLibVersion = Test;
295*67e74705SXin Li         break;
296*67e74705SXin Li       }
297*67e74705SXin Li     }
298*67e74705SXin Li     return !WindowsSDKLibVersion.empty();
299*67e74705SXin Li   }
300*67e74705SXin Li   if (Major == 10) {
301*67e74705SXin Li     if (!getWindows10SDKVersion(Path, WindowsSDKIncludeVersion))
302*67e74705SXin Li       return false;
303*67e74705SXin Li     WindowsSDKLibVersion = WindowsSDKIncludeVersion;
304*67e74705SXin Li     return true;
305*67e74705SXin Li   }
306*67e74705SXin Li   // Unsupported SDK version
307*67e74705SXin Li   return false;
308*67e74705SXin Li }
309*67e74705SXin Li 
310*67e74705SXin Li // Gets the library path required to link against the Windows SDK.
getWindowsSDKLibraryPath(std::string & path) const311*67e74705SXin Li bool MSVCToolChain::getWindowsSDKLibraryPath(std::string &path) const {
312*67e74705SXin Li   std::string sdkPath;
313*67e74705SXin Li   int sdkMajor = 0;
314*67e74705SXin Li   std::string windowsSDKIncludeVersion;
315*67e74705SXin Li   std::string windowsSDKLibVersion;
316*67e74705SXin Li 
317*67e74705SXin Li   path.clear();
318*67e74705SXin Li   if (!getWindowsSDKDir(sdkPath, sdkMajor, windowsSDKIncludeVersion,
319*67e74705SXin Li                         windowsSDKLibVersion))
320*67e74705SXin Li     return false;
321*67e74705SXin Li 
322*67e74705SXin Li   llvm::SmallString<128> libPath(sdkPath);
323*67e74705SXin Li   llvm::sys::path::append(libPath, "Lib");
324*67e74705SXin Li   if (sdkMajor <= 7) {
325*67e74705SXin Li     switch (getArch()) {
326*67e74705SXin Li     // In Windows SDK 7.x, x86 libraries are directly in the Lib folder.
327*67e74705SXin Li     case llvm::Triple::x86:
328*67e74705SXin Li       break;
329*67e74705SXin Li     case llvm::Triple::x86_64:
330*67e74705SXin Li       llvm::sys::path::append(libPath, "x64");
331*67e74705SXin Li       break;
332*67e74705SXin Li     case llvm::Triple::arm:
333*67e74705SXin Li       // It is not necessary to link against Windows SDK 7.x when targeting ARM.
334*67e74705SXin Li       return false;
335*67e74705SXin Li     default:
336*67e74705SXin Li       return false;
337*67e74705SXin Li     }
338*67e74705SXin Li   } else {
339*67e74705SXin Li     const StringRef archName = getWindowsSDKArch(getArch());
340*67e74705SXin Li     if (archName.empty())
341*67e74705SXin Li       return false;
342*67e74705SXin Li     llvm::sys::path::append(libPath, windowsSDKLibVersion, "um", archName);
343*67e74705SXin Li   }
344*67e74705SXin Li 
345*67e74705SXin Li   path = libPath.str();
346*67e74705SXin Li   return true;
347*67e74705SXin Li }
348*67e74705SXin Li 
349*67e74705SXin Li // Check if the Include path of a specified version of Visual Studio contains
350*67e74705SXin Li // specific header files. If not, they are probably shipped with Universal CRT.
useUniversalCRT(std::string & VisualStudioDir) const351*67e74705SXin Li bool clang::driver::toolchains::MSVCToolChain::useUniversalCRT(
352*67e74705SXin Li     std::string &VisualStudioDir) const {
353*67e74705SXin Li   llvm::SmallString<128> TestPath(VisualStudioDir);
354*67e74705SXin Li   llvm::sys::path::append(TestPath, "VC\\include\\stdlib.h");
355*67e74705SXin Li 
356*67e74705SXin Li   return !llvm::sys::fs::exists(TestPath);
357*67e74705SXin Li }
358*67e74705SXin Li 
getUniversalCRTSdkDir(std::string & Path,std::string & UCRTVersion) const359*67e74705SXin Li bool MSVCToolChain::getUniversalCRTSdkDir(std::string &Path,
360*67e74705SXin Li                                           std::string &UCRTVersion) const {
361*67e74705SXin Li   // vcvarsqueryregistry.bat for Visual Studio 2015 queries the registry
362*67e74705SXin Li   // for the specific key "KitsRoot10". So do we.
363*67e74705SXin Li   if (!getSystemRegistryString(
364*67e74705SXin Li           "SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots", "KitsRoot10",
365*67e74705SXin Li           Path, nullptr))
366*67e74705SXin Li     return false;
367*67e74705SXin Li 
368*67e74705SXin Li   return getWindows10SDKVersion(Path, UCRTVersion);
369*67e74705SXin Li }
370*67e74705SXin Li 
getUniversalCRTLibraryPath(std::string & Path) const371*67e74705SXin Li bool MSVCToolChain::getUniversalCRTLibraryPath(std::string &Path) const {
372*67e74705SXin Li   std::string UniversalCRTSdkPath;
373*67e74705SXin Li   std::string UCRTVersion;
374*67e74705SXin Li 
375*67e74705SXin Li   Path.clear();
376*67e74705SXin Li   if (!getUniversalCRTSdkDir(UniversalCRTSdkPath, UCRTVersion))
377*67e74705SXin Li     return false;
378*67e74705SXin Li 
379*67e74705SXin Li   StringRef ArchName = getWindowsSDKArch(getArch());
380*67e74705SXin Li   if (ArchName.empty())
381*67e74705SXin Li     return false;
382*67e74705SXin Li 
383*67e74705SXin Li   llvm::SmallString<128> LibPath(UniversalCRTSdkPath);
384*67e74705SXin Li   llvm::sys::path::append(LibPath, "Lib", UCRTVersion, "ucrt", ArchName);
385*67e74705SXin Li 
386*67e74705SXin Li   Path = LibPath.str();
387*67e74705SXin Li   return true;
388*67e74705SXin Li }
389*67e74705SXin Li 
390*67e74705SXin Li // Get the location to use for Visual Studio binaries.  The location priority
391*67e74705SXin Li // is: %VCINSTALLDIR% > %PATH% > newest copy of Visual Studio installed on
392*67e74705SXin Li // system (as reported by the registry).
getVisualStudioBinariesFolder(const char * clangProgramPath,std::string & path) const393*67e74705SXin Li bool MSVCToolChain::getVisualStudioBinariesFolder(const char *clangProgramPath,
394*67e74705SXin Li                                                   std::string &path) const {
395*67e74705SXin Li   path.clear();
396*67e74705SXin Li 
397*67e74705SXin Li   SmallString<128> BinDir;
398*67e74705SXin Li 
399*67e74705SXin Li   // First check the environment variables that vsvars32.bat sets.
400*67e74705SXin Li   llvm::Optional<std::string> VcInstallDir =
401*67e74705SXin Li       llvm::sys::Process::GetEnv("VCINSTALLDIR");
402*67e74705SXin Li   if (VcInstallDir.hasValue()) {
403*67e74705SXin Li     BinDir = VcInstallDir.getValue();
404*67e74705SXin Li     llvm::sys::path::append(BinDir, "bin");
405*67e74705SXin Li   } else {
406*67e74705SXin Li     // Next walk the PATH, trying to find a cl.exe in the path.  If we find one,
407*67e74705SXin Li     // use that.  However, make sure it's not clang's cl.exe.
408*67e74705SXin Li     llvm::Optional<std::string> OptPath = llvm::sys::Process::GetEnv("PATH");
409*67e74705SXin Li     if (OptPath.hasValue()) {
410*67e74705SXin Li       const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'};
411*67e74705SXin Li       SmallVector<StringRef, 8> PathSegments;
412*67e74705SXin Li       llvm::SplitString(OptPath.getValue(), PathSegments, EnvPathSeparatorStr);
413*67e74705SXin Li 
414*67e74705SXin Li       for (StringRef PathSegment : PathSegments) {
415*67e74705SXin Li         if (PathSegment.empty())
416*67e74705SXin Li           continue;
417*67e74705SXin Li 
418*67e74705SXin Li         SmallString<128> FilePath(PathSegment);
419*67e74705SXin Li         llvm::sys::path::append(FilePath, "cl.exe");
420*67e74705SXin Li         // Checking if cl.exe exists is a small optimization over calling
421*67e74705SXin Li         // can_execute, which really only checks for existence but will also do
422*67e74705SXin Li         // extra checks for cl.exe.exe.  These add up when walking a long path.
423*67e74705SXin Li         if (llvm::sys::fs::exists(FilePath.c_str()) &&
424*67e74705SXin Li             !llvm::sys::fs::equivalent(FilePath.c_str(), clangProgramPath)) {
425*67e74705SXin Li           // If we found it on the PATH, use it exactly as is with no
426*67e74705SXin Li           // modifications.
427*67e74705SXin Li           path = PathSegment;
428*67e74705SXin Li           return true;
429*67e74705SXin Li         }
430*67e74705SXin Li       }
431*67e74705SXin Li     }
432*67e74705SXin Li 
433*67e74705SXin Li     std::string installDir;
434*67e74705SXin Li     // With no VCINSTALLDIR and nothing on the PATH, if we can't find it in the
435*67e74705SXin Li     // registry then we have no choice but to fail.
436*67e74705SXin Li     if (!getVisualStudioInstallDir(installDir))
437*67e74705SXin Li       return false;
438*67e74705SXin Li 
439*67e74705SXin Li     // Regardless of what binary we're ultimately trying to find, we make sure
440*67e74705SXin Li     // that this is a Visual Studio directory by checking for cl.exe.  We use
441*67e74705SXin Li     // cl.exe instead of other binaries like link.exe because programs such as
442*67e74705SXin Li     // GnuWin32 also have a utility called link.exe, so cl.exe is the least
443*67e74705SXin Li     // ambiguous.
444*67e74705SXin Li     BinDir = installDir;
445*67e74705SXin Li     llvm::sys::path::append(BinDir, "VC", "bin");
446*67e74705SXin Li     SmallString<128> ClPath(BinDir);
447*67e74705SXin Li     llvm::sys::path::append(ClPath, "cl.exe");
448*67e74705SXin Li 
449*67e74705SXin Li     if (!llvm::sys::fs::can_execute(ClPath.c_str()))
450*67e74705SXin Li       return false;
451*67e74705SXin Li   }
452*67e74705SXin Li 
453*67e74705SXin Li   if (BinDir.empty())
454*67e74705SXin Li     return false;
455*67e74705SXin Li 
456*67e74705SXin Li   switch (getArch()) {
457*67e74705SXin Li   case llvm::Triple::x86:
458*67e74705SXin Li     break;
459*67e74705SXin Li   case llvm::Triple::x86_64:
460*67e74705SXin Li     llvm::sys::path::append(BinDir, "amd64");
461*67e74705SXin Li     break;
462*67e74705SXin Li   case llvm::Triple::arm:
463*67e74705SXin Li     llvm::sys::path::append(BinDir, "arm");
464*67e74705SXin Li     break;
465*67e74705SXin Li   default:
466*67e74705SXin Li     // Whatever this is, Visual Studio doesn't have a toolchain for it.
467*67e74705SXin Li     return false;
468*67e74705SXin Li   }
469*67e74705SXin Li   path = BinDir.str();
470*67e74705SXin Li   return true;
471*67e74705SXin Li }
472*67e74705SXin Li 
getMSVCVersionFromExe() const473*67e74705SXin Li VersionTuple MSVCToolChain::getMSVCVersionFromExe() const {
474*67e74705SXin Li   VersionTuple Version;
475*67e74705SXin Li #ifdef USE_WIN32
476*67e74705SXin Li   std::string BinPath;
477*67e74705SXin Li   if (!getVisualStudioBinariesFolder("", BinPath))
478*67e74705SXin Li     return Version;
479*67e74705SXin Li   SmallString<128> ClExe(BinPath);
480*67e74705SXin Li   llvm::sys::path::append(ClExe, "cl.exe");
481*67e74705SXin Li 
482*67e74705SXin Li   std::wstring ClExeWide;
483*67e74705SXin Li   if (!llvm::ConvertUTF8toWide(ClExe.c_str(), ClExeWide))
484*67e74705SXin Li     return Version;
485*67e74705SXin Li 
486*67e74705SXin Li   const DWORD VersionSize = ::GetFileVersionInfoSizeW(ClExeWide.c_str(),
487*67e74705SXin Li                                                       nullptr);
488*67e74705SXin Li   if (VersionSize == 0)
489*67e74705SXin Li     return Version;
490*67e74705SXin Li 
491*67e74705SXin Li   SmallVector<uint8_t, 4 * 1024> VersionBlock(VersionSize);
492*67e74705SXin Li   if (!::GetFileVersionInfoW(ClExeWide.c_str(), 0, VersionSize,
493*67e74705SXin Li                              VersionBlock.data()))
494*67e74705SXin Li     return Version;
495*67e74705SXin Li 
496*67e74705SXin Li   VS_FIXEDFILEINFO *FileInfo = nullptr;
497*67e74705SXin Li   UINT FileInfoSize = 0;
498*67e74705SXin Li   if (!::VerQueryValueW(VersionBlock.data(), L"\\",
499*67e74705SXin Li                         reinterpret_cast<LPVOID *>(&FileInfo), &FileInfoSize) ||
500*67e74705SXin Li       FileInfoSize < sizeof(*FileInfo))
501*67e74705SXin Li     return Version;
502*67e74705SXin Li 
503*67e74705SXin Li   const unsigned Major = (FileInfo->dwFileVersionMS >> 16) & 0xFFFF;
504*67e74705SXin Li   const unsigned Minor = (FileInfo->dwFileVersionMS      ) & 0xFFFF;
505*67e74705SXin Li   const unsigned Micro = (FileInfo->dwFileVersionLS >> 16) & 0xFFFF;
506*67e74705SXin Li 
507*67e74705SXin Li   Version = VersionTuple(Major, Minor, Micro);
508*67e74705SXin Li #endif
509*67e74705SXin Li   return Version;
510*67e74705SXin Li }
511*67e74705SXin Li 
512*67e74705SXin Li // Get Visual Studio installation directory.
getVisualStudioInstallDir(std::string & path) const513*67e74705SXin Li bool MSVCToolChain::getVisualStudioInstallDir(std::string &path) const {
514*67e74705SXin Li   // First check the environment variables that vsvars32.bat sets.
515*67e74705SXin Li   const char *vcinstalldir = getenv("VCINSTALLDIR");
516*67e74705SXin Li   if (vcinstalldir) {
517*67e74705SXin Li     path = vcinstalldir;
518*67e74705SXin Li     path = path.substr(0, path.find("\\VC"));
519*67e74705SXin Li     return true;
520*67e74705SXin Li   }
521*67e74705SXin Li 
522*67e74705SXin Li   std::string vsIDEInstallDir;
523*67e74705SXin Li   std::string vsExpressIDEInstallDir;
524*67e74705SXin Li   // Then try the windows registry.
525*67e74705SXin Li   bool hasVCDir =
526*67e74705SXin Li       getSystemRegistryString("SOFTWARE\\Microsoft\\VisualStudio\\$VERSION",
527*67e74705SXin Li                               "InstallDir", vsIDEInstallDir, nullptr);
528*67e74705SXin Li   if (hasVCDir && !vsIDEInstallDir.empty()) {
529*67e74705SXin Li     path = vsIDEInstallDir.substr(0, vsIDEInstallDir.find("\\Common7\\IDE"));
530*67e74705SXin Li     return true;
531*67e74705SXin Li   }
532*67e74705SXin Li 
533*67e74705SXin Li   bool hasVCExpressDir =
534*67e74705SXin Li       getSystemRegistryString("SOFTWARE\\Microsoft\\VCExpress\\$VERSION",
535*67e74705SXin Li                               "InstallDir", vsExpressIDEInstallDir, nullptr);
536*67e74705SXin Li   if (hasVCExpressDir && !vsExpressIDEInstallDir.empty()) {
537*67e74705SXin Li     path = vsExpressIDEInstallDir.substr(
538*67e74705SXin Li         0, vsIDEInstallDir.find("\\Common7\\IDE"));
539*67e74705SXin Li     return true;
540*67e74705SXin Li   }
541*67e74705SXin Li 
542*67e74705SXin Li   // Try the environment.
543*67e74705SXin Li   const char *vs120comntools = getenv("VS120COMNTOOLS");
544*67e74705SXin Li   const char *vs100comntools = getenv("VS100COMNTOOLS");
545*67e74705SXin Li   const char *vs90comntools = getenv("VS90COMNTOOLS");
546*67e74705SXin Li   const char *vs80comntools = getenv("VS80COMNTOOLS");
547*67e74705SXin Li 
548*67e74705SXin Li   const char *vscomntools = nullptr;
549*67e74705SXin Li 
550*67e74705SXin Li   // Find any version we can
551*67e74705SXin Li   if (vs120comntools)
552*67e74705SXin Li     vscomntools = vs120comntools;
553*67e74705SXin Li   else if (vs100comntools)
554*67e74705SXin Li     vscomntools = vs100comntools;
555*67e74705SXin Li   else if (vs90comntools)
556*67e74705SXin Li     vscomntools = vs90comntools;
557*67e74705SXin Li   else if (vs80comntools)
558*67e74705SXin Li     vscomntools = vs80comntools;
559*67e74705SXin Li 
560*67e74705SXin Li   if (vscomntools && *vscomntools) {
561*67e74705SXin Li     const char *p = strstr(vscomntools, "\\Common7\\Tools");
562*67e74705SXin Li     path = p ? std::string(vscomntools, p) : vscomntools;
563*67e74705SXin Li     return true;
564*67e74705SXin Li   }
565*67e74705SXin Li   return false;
566*67e74705SXin Li }
567*67e74705SXin Li 
AddSystemIncludeWithSubfolder(const ArgList & DriverArgs,ArgStringList & CC1Args,const std::string & folder,const Twine & subfolder1,const Twine & subfolder2,const Twine & subfolder3) const568*67e74705SXin Li void MSVCToolChain::AddSystemIncludeWithSubfolder(
569*67e74705SXin Li     const ArgList &DriverArgs, ArgStringList &CC1Args,
570*67e74705SXin Li     const std::string &folder, const Twine &subfolder1, const Twine &subfolder2,
571*67e74705SXin Li     const Twine &subfolder3) const {
572*67e74705SXin Li   llvm::SmallString<128> path(folder);
573*67e74705SXin Li   llvm::sys::path::append(path, subfolder1, subfolder2, subfolder3);
574*67e74705SXin Li   addSystemInclude(DriverArgs, CC1Args, path);
575*67e74705SXin Li }
576*67e74705SXin Li 
AddClangSystemIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const577*67e74705SXin Li void MSVCToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
578*67e74705SXin Li                                               ArgStringList &CC1Args) const {
579*67e74705SXin Li   if (DriverArgs.hasArg(options::OPT_nostdinc))
580*67e74705SXin Li     return;
581*67e74705SXin Li 
582*67e74705SXin Li   if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
583*67e74705SXin Li     AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, getDriver().ResourceDir,
584*67e74705SXin Li                                   "include");
585*67e74705SXin Li   }
586*67e74705SXin Li 
587*67e74705SXin Li   // Add %INCLUDE%-like directories from the -imsvc flag.
588*67e74705SXin Li   for (const auto &Path : DriverArgs.getAllArgValues(options::OPT__SLASH_imsvc))
589*67e74705SXin Li     addSystemInclude(DriverArgs, CC1Args, Path);
590*67e74705SXin Li 
591*67e74705SXin Li   if (DriverArgs.hasArg(options::OPT_nostdlibinc))
592*67e74705SXin Li     return;
593*67e74705SXin Li 
594*67e74705SXin Li   // Honor %INCLUDE%. It should know essential search paths with vcvarsall.bat.
595*67e74705SXin Li   if (const char *cl_include_dir = getenv("INCLUDE")) {
596*67e74705SXin Li     SmallVector<StringRef, 8> Dirs;
597*67e74705SXin Li     StringRef(cl_include_dir)
598*67e74705SXin Li         .split(Dirs, ";", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
599*67e74705SXin Li     for (StringRef Dir : Dirs)
600*67e74705SXin Li       addSystemInclude(DriverArgs, CC1Args, Dir);
601*67e74705SXin Li     if (!Dirs.empty())
602*67e74705SXin Li       return;
603*67e74705SXin Li   }
604*67e74705SXin Li 
605*67e74705SXin Li   std::string VSDir;
606*67e74705SXin Li 
607*67e74705SXin Li   // When built with access to the proper Windows APIs, try to actually find
608*67e74705SXin Li   // the correct include paths first.
609*67e74705SXin Li   if (getVisualStudioInstallDir(VSDir)) {
610*67e74705SXin Li     AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, VSDir, "VC\\include");
611*67e74705SXin Li 
612*67e74705SXin Li     if (useUniversalCRT(VSDir)) {
613*67e74705SXin Li       std::string UniversalCRTSdkPath;
614*67e74705SXin Li       std::string UCRTVersion;
615*67e74705SXin Li       if (getUniversalCRTSdkDir(UniversalCRTSdkPath, UCRTVersion)) {
616*67e74705SXin Li         AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, UniversalCRTSdkPath,
617*67e74705SXin Li                                       "Include", UCRTVersion, "ucrt");
618*67e74705SXin Li       }
619*67e74705SXin Li     }
620*67e74705SXin Li 
621*67e74705SXin Li     std::string WindowsSDKDir;
622*67e74705SXin Li     int major;
623*67e74705SXin Li     std::string windowsSDKIncludeVersion;
624*67e74705SXin Li     std::string windowsSDKLibVersion;
625*67e74705SXin Li     if (getWindowsSDKDir(WindowsSDKDir, major, windowsSDKIncludeVersion,
626*67e74705SXin Li                          windowsSDKLibVersion)) {
627*67e74705SXin Li       if (major >= 8) {
628*67e74705SXin Li         // Note: windowsSDKIncludeVersion is empty for SDKs prior to v10.
629*67e74705SXin Li         // Anyway, llvm::sys::path::append is able to manage it.
630*67e74705SXin Li         AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
631*67e74705SXin Li                                       "include", windowsSDKIncludeVersion,
632*67e74705SXin Li                                       "shared");
633*67e74705SXin Li         AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
634*67e74705SXin Li                                       "include", windowsSDKIncludeVersion,
635*67e74705SXin Li                                       "um");
636*67e74705SXin Li         AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
637*67e74705SXin Li                                       "include", windowsSDKIncludeVersion,
638*67e74705SXin Li                                       "winrt");
639*67e74705SXin Li       } else {
640*67e74705SXin Li         AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
641*67e74705SXin Li                                       "include");
642*67e74705SXin Li       }
643*67e74705SXin Li     } else {
644*67e74705SXin Li       addSystemInclude(DriverArgs, CC1Args, VSDir);
645*67e74705SXin Li     }
646*67e74705SXin Li     return;
647*67e74705SXin Li   }
648*67e74705SXin Li 
649*67e74705SXin Li   // As a fallback, select default install paths.
650*67e74705SXin Li   // FIXME: Don't guess drives and paths like this on Windows.
651*67e74705SXin Li   const StringRef Paths[] = {
652*67e74705SXin Li     "C:/Program Files/Microsoft Visual Studio 10.0/VC/include",
653*67e74705SXin Li     "C:/Program Files/Microsoft Visual Studio 9.0/VC/include",
654*67e74705SXin Li     "C:/Program Files/Microsoft Visual Studio 9.0/VC/PlatformSDK/Include",
655*67e74705SXin Li     "C:/Program Files/Microsoft Visual Studio 8/VC/include",
656*67e74705SXin Li     "C:/Program Files/Microsoft Visual Studio 8/VC/PlatformSDK/Include"
657*67e74705SXin Li   };
658*67e74705SXin Li   addSystemIncludes(DriverArgs, CC1Args, Paths);
659*67e74705SXin Li }
660*67e74705SXin Li 
AddClangCXXStdlibIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const661*67e74705SXin Li void MSVCToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
662*67e74705SXin Li                                                  ArgStringList &CC1Args) const {
663*67e74705SXin Li   // FIXME: There should probably be logic here to find libc++ on Windows.
664*67e74705SXin Li }
665*67e74705SXin Li 
666*67e74705SXin Li std::string
ComputeEffectiveClangTriple(const ArgList & Args,types::ID InputType) const667*67e74705SXin Li MSVCToolChain::ComputeEffectiveClangTriple(const ArgList &Args,
668*67e74705SXin Li                                            types::ID InputType) const {
669*67e74705SXin Li   std::string TripleStr =
670*67e74705SXin Li       ToolChain::ComputeEffectiveClangTriple(Args, InputType);
671*67e74705SXin Li   llvm::Triple Triple(TripleStr);
672*67e74705SXin Li   VersionTuple MSVT =
673*67e74705SXin Li       tools::visualstudio::getMSVCVersion(/*D=*/nullptr, *this, Triple, Args,
674*67e74705SXin Li                                           /*IsWindowsMSVC=*/true);
675*67e74705SXin Li   if (MSVT.empty())
676*67e74705SXin Li     return TripleStr;
677*67e74705SXin Li 
678*67e74705SXin Li   MSVT = VersionTuple(MSVT.getMajor(), MSVT.getMinor().getValueOr(0),
679*67e74705SXin Li                       MSVT.getSubminor().getValueOr(0));
680*67e74705SXin Li 
681*67e74705SXin Li   if (Triple.getEnvironment() == llvm::Triple::MSVC) {
682*67e74705SXin Li     StringRef ObjFmt = Triple.getEnvironmentName().split('-').second;
683*67e74705SXin Li     if (ObjFmt.empty())
684*67e74705SXin Li       Triple.setEnvironmentName((Twine("msvc") + MSVT.getAsString()).str());
685*67e74705SXin Li     else
686*67e74705SXin Li       Triple.setEnvironmentName(
687*67e74705SXin Li           (Twine("msvc") + MSVT.getAsString() + Twine('-') + ObjFmt).str());
688*67e74705SXin Li   }
689*67e74705SXin Li   return Triple.getTriple();
690*67e74705SXin Li }
691*67e74705SXin Li 
getSupportedSanitizers() const692*67e74705SXin Li SanitizerMask MSVCToolChain::getSupportedSanitizers() const {
693*67e74705SXin Li   SanitizerMask Res = ToolChain::getSupportedSanitizers();
694*67e74705SXin Li   Res |= SanitizerKind::Address;
695*67e74705SXin Li   return Res;
696*67e74705SXin Li }
697*67e74705SXin Li 
TranslateOptArg(Arg * A,llvm::opt::DerivedArgList & DAL,bool SupportsForcingFramePointer,const char * ExpandChar,const OptTable & Opts)698*67e74705SXin Li static void TranslateOptArg(Arg *A, llvm::opt::DerivedArgList &DAL,
699*67e74705SXin Li                             bool SupportsForcingFramePointer,
700*67e74705SXin Li                             const char *ExpandChar, const OptTable &Opts) {
701*67e74705SXin Li   assert(A->getOption().matches(options::OPT__SLASH_O));
702*67e74705SXin Li 
703*67e74705SXin Li   StringRef OptStr = A->getValue();
704*67e74705SXin Li   for (size_t I = 0, E = OptStr.size(); I != E; ++I) {
705*67e74705SXin Li     const char &OptChar = *(OptStr.data() + I);
706*67e74705SXin Li     switch (OptChar) {
707*67e74705SXin Li     default:
708*67e74705SXin Li       break;
709*67e74705SXin Li     case '1':
710*67e74705SXin Li     case '2':
711*67e74705SXin Li     case 'x':
712*67e74705SXin Li     case 'd':
713*67e74705SXin Li       if (&OptChar == ExpandChar) {
714*67e74705SXin Li         if (OptChar == 'd') {
715*67e74705SXin Li           DAL.AddFlagArg(A, Opts.getOption(options::OPT_O0));
716*67e74705SXin Li         } else {
717*67e74705SXin Li           if (OptChar == '1') {
718*67e74705SXin Li             DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "s");
719*67e74705SXin Li           } else if (OptChar == '2' || OptChar == 'x') {
720*67e74705SXin Li             DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
721*67e74705SXin Li             DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "2");
722*67e74705SXin Li           }
723*67e74705SXin Li           if (SupportsForcingFramePointer &&
724*67e74705SXin Li               !DAL.hasArgNoClaim(options::OPT_fno_omit_frame_pointer))
725*67e74705SXin Li             DAL.AddFlagArg(A,
726*67e74705SXin Li                            Opts.getOption(options::OPT_fomit_frame_pointer));
727*67e74705SXin Li           if (OptChar == '1' || OptChar == '2')
728*67e74705SXin Li             DAL.AddFlagArg(A,
729*67e74705SXin Li                            Opts.getOption(options::OPT_ffunction_sections));
730*67e74705SXin Li         }
731*67e74705SXin Li       }
732*67e74705SXin Li       break;
733*67e74705SXin Li     case 'b':
734*67e74705SXin Li       if (I + 1 != E && isdigit(OptStr[I + 1])) {
735*67e74705SXin Li         switch (OptStr[I + 1]) {
736*67e74705SXin Li         case '0':
737*67e74705SXin Li           DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_inline));
738*67e74705SXin Li           break;
739*67e74705SXin Li         case '1':
740*67e74705SXin Li           DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_hint_functions));
741*67e74705SXin Li           break;
742*67e74705SXin Li         case '2':
743*67e74705SXin Li           DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_functions));
744*67e74705SXin Li           break;
745*67e74705SXin Li         }
746*67e74705SXin Li         ++I;
747*67e74705SXin Li       }
748*67e74705SXin Li       break;
749*67e74705SXin Li     case 'g':
750*67e74705SXin Li       break;
751*67e74705SXin Li     case 'i':
752*67e74705SXin Li       if (I + 1 != E && OptStr[I + 1] == '-') {
753*67e74705SXin Li         ++I;
754*67e74705SXin Li         DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_builtin));
755*67e74705SXin Li       } else {
756*67e74705SXin Li         DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
757*67e74705SXin Li       }
758*67e74705SXin Li       break;
759*67e74705SXin Li     case 's':
760*67e74705SXin Li       DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "s");
761*67e74705SXin Li       break;
762*67e74705SXin Li     case 't':
763*67e74705SXin Li       DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "2");
764*67e74705SXin Li       break;
765*67e74705SXin Li     case 'y': {
766*67e74705SXin Li       bool OmitFramePointer = true;
767*67e74705SXin Li       if (I + 1 != E && OptStr[I + 1] == '-') {
768*67e74705SXin Li         OmitFramePointer = false;
769*67e74705SXin Li         ++I;
770*67e74705SXin Li       }
771*67e74705SXin Li       if (SupportsForcingFramePointer) {
772*67e74705SXin Li         if (OmitFramePointer)
773*67e74705SXin Li           DAL.AddFlagArg(A,
774*67e74705SXin Li                          Opts.getOption(options::OPT_fomit_frame_pointer));
775*67e74705SXin Li         else
776*67e74705SXin Li           DAL.AddFlagArg(
777*67e74705SXin Li               A, Opts.getOption(options::OPT_fno_omit_frame_pointer));
778*67e74705SXin Li       } else {
779*67e74705SXin Li         // Don't warn about /Oy- in 64-bit builds (where
780*67e74705SXin Li         // SupportsForcingFramePointer is false).  The flag having no effect
781*67e74705SXin Li         // there is a compiler-internal optimization, and people shouldn't have
782*67e74705SXin Li         // to special-case their build files for 64-bit clang-cl.
783*67e74705SXin Li         A->claim();
784*67e74705SXin Li       }
785*67e74705SXin Li       break;
786*67e74705SXin Li     }
787*67e74705SXin Li     }
788*67e74705SXin Li   }
789*67e74705SXin Li }
790*67e74705SXin Li 
TranslateDArg(Arg * A,llvm::opt::DerivedArgList & DAL,const OptTable & Opts)791*67e74705SXin Li static void TranslateDArg(Arg *A, llvm::opt::DerivedArgList &DAL,
792*67e74705SXin Li                           const OptTable &Opts) {
793*67e74705SXin Li   assert(A->getOption().matches(options::OPT_D));
794*67e74705SXin Li 
795*67e74705SXin Li   StringRef Val = A->getValue();
796*67e74705SXin Li   size_t Hash = Val.find('#');
797*67e74705SXin Li   if (Hash == StringRef::npos || Hash > Val.find('=')) {
798*67e74705SXin Li     DAL.append(A);
799*67e74705SXin Li     return;
800*67e74705SXin Li   }
801*67e74705SXin Li 
802*67e74705SXin Li   std::string NewVal = Val;
803*67e74705SXin Li   NewVal[Hash] = '=';
804*67e74705SXin Li   DAL.AddJoinedArg(A, Opts.getOption(options::OPT_D), NewVal);
805*67e74705SXin Li }
806*67e74705SXin Li 
807*67e74705SXin Li llvm::opt::DerivedArgList *
TranslateArgs(const llvm::opt::DerivedArgList & Args,const char * BoundArch) const808*67e74705SXin Li MSVCToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args,
809*67e74705SXin Li                              const char *BoundArch) const {
810*67e74705SXin Li   DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
811*67e74705SXin Li   const OptTable &Opts = getDriver().getOpts();
812*67e74705SXin Li 
813*67e74705SXin Li   // /Oy and /Oy- only has an effect under X86-32.
814*67e74705SXin Li   bool SupportsForcingFramePointer = getArch() == llvm::Triple::x86;
815*67e74705SXin Li 
816*67e74705SXin Li   // The -O[12xd] flag actually expands to several flags.  We must desugar the
817*67e74705SXin Li   // flags so that options embedded can be negated.  For example, the '-O2' flag
818*67e74705SXin Li   // enables '-Oy'.  Expanding '-O2' into its constituent flags allows us to
819*67e74705SXin Li   // correctly handle '-O2 -Oy-' where the trailing '-Oy-' disables a single
820*67e74705SXin Li   // aspect of '-O2'.
821*67e74705SXin Li   //
822*67e74705SXin Li   // Note that this expansion logic only applies to the *last* of '[12xd]'.
823*67e74705SXin Li 
824*67e74705SXin Li   // First step is to search for the character we'd like to expand.
825*67e74705SXin Li   const char *ExpandChar = nullptr;
826*67e74705SXin Li   for (Arg *A : Args) {
827*67e74705SXin Li     if (!A->getOption().matches(options::OPT__SLASH_O))
828*67e74705SXin Li       continue;
829*67e74705SXin Li     StringRef OptStr = A->getValue();
830*67e74705SXin Li     for (size_t I = 0, E = OptStr.size(); I != E; ++I) {
831*67e74705SXin Li       char OptChar = OptStr[I];
832*67e74705SXin Li       char PrevChar = I > 0 ? OptStr[I - 1] : '0';
833*67e74705SXin Li       if (PrevChar == 'b') {
834*67e74705SXin Li         // OptChar does not expand; it's an argument to the previous char.
835*67e74705SXin Li         continue;
836*67e74705SXin Li       }
837*67e74705SXin Li       if (OptChar == '1' || OptChar == '2' || OptChar == 'x' || OptChar == 'd')
838*67e74705SXin Li         ExpandChar = OptStr.data() + I;
839*67e74705SXin Li     }
840*67e74705SXin Li   }
841*67e74705SXin Li 
842*67e74705SXin Li   for (Arg *A : Args) {
843*67e74705SXin Li     if (A->getOption().matches(options::OPT__SLASH_O)) {
844*67e74705SXin Li       // The -O flag actually takes an amalgam of other options.  For example,
845*67e74705SXin Li       // '/Ogyb2' is equivalent to '/Og' '/Oy' '/Ob2'.
846*67e74705SXin Li       TranslateOptArg(A, *DAL, SupportsForcingFramePointer, ExpandChar, Opts);
847*67e74705SXin Li     } else if (A->getOption().matches(options::OPT_D)) {
848*67e74705SXin Li       // Translate -Dfoo#bar into -Dfoo=bar.
849*67e74705SXin Li       TranslateDArg(A, *DAL, Opts);
850*67e74705SXin Li     } else {
851*67e74705SXin Li       DAL->append(A);
852*67e74705SXin Li     }
853*67e74705SXin Li   }
854*67e74705SXin Li 
855*67e74705SXin Li   return DAL;
856*67e74705SXin Li }
857