clang  3.8.0
MSVCToolChain.cpp
Go to the documentation of this file.
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"
15 #include "clang/Driver/Driver.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 
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 
56  return new tools::visualstudio::Linker(*this);
57 }
58 
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 
67  return true;
68 }
69 
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 
78  return getArch() == llvm::Triple::x86_64;
79 }
80 
82  return false;
83 }
84 
86  return getArch() == llvm::Triple::x86_64;
87 }
88 
89 #ifdef USE_WIN32
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.
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
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.
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.
252 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.
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.
296 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.
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 
345  std::string &UCRTVersion) const {
346  // vcvarsqueryregistry.bat for Visual Studio 2015 queries the registry
347  // for the specific key "KitsRoot10". So do we.
349  "SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots", "KitsRoot10",
350  Path, nullptr))
351  return false;
352 
353  return getWindows10SDKVersion(Path, UCRTVersion);
354 }
355 
356 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).
378 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.
456 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 
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 
520 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")) {
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 
600 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
607  types::ID InputType) const {
608  std::string TripleStr =
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 
633  Res |= SanitizerKind::Address;
634  return Res;
635 }
636 
637 static void TranslateOptArg(Arg *A, llvm::opt::DerivedArgList &DAL,
638  bool SupportsForcingFramePointer,
639  const char *ExpandChar, const OptTable &Opts) {
640  assert(A->getOption().matches(options::OPT__SLASH_O));
641 
642  StringRef OptStr = A->getValue();
643  for (size_t I = 0, E = OptStr.size(); I != E; ++I) {
644  const char &OptChar = *(OptStr.data() + I);
645  switch (OptChar) {
646  default:
647  break;
648  case '1':
649  case '2':
650  case 'x':
651  case 'd':
652  if (&OptChar == ExpandChar) {
653  if (OptChar == 'd') {
654  DAL.AddFlagArg(A, Opts.getOption(options::OPT_O0));
655  } else {
656  if (OptChar == '1') {
657  DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "s");
658  } else if (OptChar == '2' || OptChar == 'x') {
659  DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
660  DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "2");
661  }
662  if (SupportsForcingFramePointer)
663  DAL.AddFlagArg(A,
664  Opts.getOption(options::OPT_fomit_frame_pointer));
665  if (OptChar == '1' || OptChar == '2')
666  DAL.AddFlagArg(A,
667  Opts.getOption(options::OPT_ffunction_sections));
668  }
669  }
670  break;
671  case 'b':
672  if (I + 1 != E && isdigit(OptStr[I + 1]))
673  ++I;
674  break;
675  case 'g':
676  break;
677  case 'i':
678  if (I + 1 != E && OptStr[I + 1] == '-') {
679  ++I;
680  DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_builtin));
681  } else {
682  DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
683  }
684  break;
685  case 's':
686  DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "s");
687  break;
688  case 't':
689  DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "2");
690  break;
691  case 'y': {
692  bool OmitFramePointer = true;
693  if (I + 1 != E && OptStr[I + 1] == '-') {
694  OmitFramePointer = false;
695  ++I;
696  }
697  if (SupportsForcingFramePointer) {
698  if (OmitFramePointer)
699  DAL.AddFlagArg(A,
700  Opts.getOption(options::OPT_fomit_frame_pointer));
701  else
702  DAL.AddFlagArg(
703  A, Opts.getOption(options::OPT_fno_omit_frame_pointer));
704  }
705  break;
706  }
707  }
708  }
709 }
710 
711 static void TranslateDArg(Arg *A, llvm::opt::DerivedArgList &DAL,
712  const OptTable &Opts) {
713  assert(A->getOption().matches(options::OPT_D));
714 
715  StringRef Val = A->getValue();
716  size_t Hash = Val.find('#');
717  if (Hash == StringRef::npos || Hash > Val.find('=')) {
718  DAL.append(A);
719  return;
720  }
721 
722  std::string NewVal = Val;
723  NewVal[Hash] = '=';
724  DAL.AddJoinedArg(A, Opts.getOption(options::OPT_D), NewVal);
725 }
726 
727 llvm::opt::DerivedArgList *
728 MSVCToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args,
729  const char *BoundArch) const {
730  DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
731  const OptTable &Opts = getDriver().getOpts();
732 
733  // /Oy and /Oy- only has an effect under X86-32.
734  bool SupportsForcingFramePointer = getArch() == llvm::Triple::x86;
735 
736  // The -O[12xd] flag actually expands to several flags. We must desugar the
737  // flags so that options embedded can be negated. For example, the '-O2' flag
738  // enables '-Oy'. Expanding '-O2' into its constituent flags allows us to
739  // correctly handle '-O2 -Oy-' where the trailing '-Oy-' disables a single
740  // aspect of '-O2'.
741  //
742  // Note that this expansion logic only applies to the *last* of '[12xd]'.
743 
744  // First step is to search for the character we'd like to expand.
745  const char *ExpandChar = nullptr;
746  for (Arg *A : Args) {
747  if (!A->getOption().matches(options::OPT__SLASH_O))
748  continue;
749  StringRef OptStr = A->getValue();
750  for (size_t I = 0, E = OptStr.size(); I != E; ++I) {
751  const char &OptChar = *(OptStr.data() + I);
752  if (OptChar == '1' || OptChar == '2' || OptChar == 'x' || OptChar == 'd')
753  ExpandChar = OptStr.data() + I;
754  }
755  }
756 
757  for (Arg *A : Args) {
758  if (A->getOption().matches(options::OPT__SLASH_O)) {
759  // The -O flag actually takes an amalgam of other options. For example,
760  // '/Ogyb2' is equivalent to '/Og' '/Oy' '/Ob2'.
761  TranslateOptArg(A, *DAL, SupportsForcingFramePointer, ExpandChar, Opts);
762  } else if (A->getOption().matches(options::OPT_D)) {
763  // Translate -Dfoo#bar into -Dfoo=bar.
764  TranslateDArg(A, *DAL, Opts);
765  } else {
766  DAL->append(A);
767  }
768  }
769 
770  return DAL;
771 }
const llvm::Triple & getTriple() const
Definition: ToolChain.h:129
static LLVM_READONLY bool isDigit(unsigned char c)
Return true if this character is an ASCII digit: [0-9].
Definition: CharInfo.h:94
bool IsIntegratedAssemblerDefault() const override
IsIntegratedAssemblerDefault - Does this tool chain enable -integrated-as by default.
Represents a version number in the form major[.minor[.subminor[.build]]].
Definition: VersionTuple.h:26
Optional< unsigned > getMinor() const
Retrieve the minor version number, if provided.
Definition: VersionTuple.h:72
std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args, types::ID InputType) const override
ComputeEffectiveClangTriple - Return the Clang triple to use for this target, which may take into acc...
const llvm::opt::OptTable & getOpts() const
Definition: Driver.h:233
bool isPIEDefault() const override
Test whether this toolchain defaults to PIE.
DiagnosticBuilder Diag(unsigned DiagID) const
Definition: Driver.h:90
llvm::Triple::ArchType getArch() const
Definition: ToolChain.h:131
virtual SanitizerMask getSupportedSanitizers() const
Return sanitizers which are available in this toolchain.
Definition: ToolChain.cpp:655
bool getVisualStudioInstallDir(std::string &path) const
const StringRef FilePath
void AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override
AddClangCXXStdlibIncludeArgs - Add the clang -cc1 level arguments to set the include paths to use for...
bool getUniversalCRTLibraryPath(std::string &path) const
path_list & getProgramPaths()
Definition: ToolChain.h:147
static void TranslateDArg(Arg *A, llvm::opt::DerivedArgList &DAL, const OptTable &Opts)
std::string getAsString() const
Retrieve a string representation of the version number.
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
Definition: Driver.h:65
const Driver & getDriver() const
Definition: ToolChain.h:127
bool getUniversalCRTSdkDir(std::string &path, std::string &ucrtVersion) const
detail::InMemoryDirectory::const_iterator I
static void TranslateOptArg(Arg *A, llvm::opt::DerivedArgList &DAL, bool SupportsForcingFramePointer, const char *ExpandChar, const OptTable &Opts)
bool isPICDefault() const override
Test whether this toolchain defaults to PIC.
static StringRef getWindowsSDKArch(llvm::Triple::ArchType Arch)
void AddSystemIncludeWithSubfolder(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, const std::string &folder, const Twine &subfolder1, const Twine &subfolder2="", const Twine &subfolder3="") const
static void addSystemIncludes(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, ArrayRef< StringRef > Paths)
Utility function to add a list of system include directories to CC1.
Definition: ToolChain.cpp:581
VersionTuple getMSVCVersion(const Driver *D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args, bool IsWindowsMSVC)
Definition: Tools.cpp:3095
#define NULL
Definition: stddef.h:105
Defines version macros and version-related utility functions for Clang.
void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override
Add the clang cc1 arguments for system include paths.
bool getWindowsSDKDir(std::string &path, int &major, std::string &windowsSDKIncludeVersion, std::string &windowsSDKLibVersion) const
Get Windows SDK installation directory.
bool IsUnwindTablesDefault() const override
IsUnwindTablesDefault - Does this tool chain use -funwind-tables by default.
static bool getSystemRegistryString(const char *keyPath, const char *valueName, std::string &value, std::string *phValue)
Read registry string.
bool getWindowsSDKLibraryPath(std::string &path) const
unsigned getMajor() const
Retrieve the major version number.
Definition: VersionTuple.h:69
virtual std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args, types::ID InputType=types::TY_INVALID) const
ComputeEffectiveClangTriple - Return the Clang triple to use for this target, which may take into acc...
Definition: ToolChain.cpp:497
static void addSystemInclude(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, const Twine &Path)
Utility function to add a system include directory to CC1 arguments.
Definition: ToolChain.cpp:551
bool getVisualStudioBinariesFolder(const char *clangProgramPath, std::string &path) const
llvm::opt::DerivedArgList * TranslateArgs(const llvm::opt::DerivedArgList &Args, const char *BoundArch) const override
TranslateArgs - Create a new derived argument list for any argument translations this ToolChain may w...
uint64_t SanitizerMask
Definition: Sanitizers.h:24
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
Definition: ASTMatchers.h:1723
bool empty() const
Determine whether this version information is empty (e.g., all version components are zero)...
Definition: VersionTuple.h:64
static __inline__ uint32_t volatile uint32_t * p
Definition: arm_acle.h:75
Tool - Information on a specific compilation tool.
Definition: Tool.h:34
detail::InMemoryDirectory::const_iterator E
bool useUniversalCRT(std::string &visualStudioDir) const
Check if Universal CRT should be used if available.
Optional< unsigned > getSubminor() const
Retrieve the subminor version number, if provided.
Definition: VersionTuple.h:79
MSVCToolChain(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args)
static bool getWindows10SDKVersion(const std::string &SDKPath, std::string &SDKVersion)
SanitizerMask getSupportedSanitizers() const override
Return sanitizers which are available in this toolchain.
ToolChain - Access to tools for a single platform.
Definition: ToolChain.h:47
bool isPICDefaultForced() const override
Tests whether this toolchain forces its default for PIC, PIE or non-PIC.