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