LLVM  16.0.0git
MSVCPaths.cpp
Go to the documentation of this file.
1 //===-- MSVCPaths.cpp - MSVC path-parsing helpers -------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
10 #include "llvm/ADT/Optional.h"
11 #include "llvm/ADT/SmallString.h"
12 #include "llvm/ADT/SmallVector.h"
13 #include "llvm/ADT/StringRef.h"
14 #include "llvm/ADT/Triple.h"
15 #include "llvm/ADT/Twine.h"
16 #include "llvm/Support/Host.h"
17 #include "llvm/Support/Path.h"
18 #include "llvm/Support/Process.h"
19 #include "llvm/Support/Program.h"
22 #include <string>
23 
24 #ifdef _WIN32
26 #endif
27 
28 #ifdef _WIN32
29 #define WIN32_LEAN_AND_MEAN
30 #define NOGDI
31 #ifndef NOMINMAX
32 #define NOMINMAX
33 #endif
34 #include <windows.h>
35 #endif
36 
37 #ifdef _MSC_VER
38 // Don't support SetupApi on MinGW.
39 #define USE_MSVC_SETUP_API
40 
41 // Make sure this comes before MSVCSetupApi.h
42 #include <comdef.h>
43 
44 #include "llvm/Support/COM.h"
45 #ifdef __clang__
46 #pragma clang diagnostic push
47 #pragma clang diagnostic ignored "-Wnon-virtual-dtor"
48 #endif
50 #ifdef __clang__
51 #pragma clang diagnostic pop
52 #endif
53 _COM_SMARTPTR_TYPEDEF(ISetupConfiguration, __uuidof(ISetupConfiguration));
54 _COM_SMARTPTR_TYPEDEF(ISetupConfiguration2, __uuidof(ISetupConfiguration2));
55 _COM_SMARTPTR_TYPEDEF(ISetupHelper, __uuidof(ISetupHelper));
56 _COM_SMARTPTR_TYPEDEF(IEnumSetupInstances, __uuidof(IEnumSetupInstances));
57 _COM_SMARTPTR_TYPEDEF(ISetupInstance, __uuidof(ISetupInstance));
58 _COM_SMARTPTR_TYPEDEF(ISetupInstance2, __uuidof(ISetupInstance2));
59 #endif
60 
61 static std::string
63  llvm::StringRef Directory) {
64  std::string Highest;
65  llvm::VersionTuple HighestTuple;
66 
67  std::error_code EC;
68  for (llvm::vfs::directory_iterator DirIt = VFS.dir_begin(Directory, EC),
69  DirEnd;
70  !EC && DirIt != DirEnd; DirIt.increment(EC)) {
71  auto Status = VFS.status(DirIt->path());
72  if (!Status || !Status->isDirectory())
73  continue;
74  llvm::StringRef CandidateName = llvm::sys::path::filename(DirIt->path());
75  llvm::VersionTuple Tuple;
76  if (Tuple.tryParse(CandidateName)) // tryParse() returns true on error.
77  continue;
78  if (Tuple > HighestTuple) {
79  HighestTuple = Tuple;
80  Highest = CandidateName.str();
81  }
82  }
83 
84  return Highest;
85 }
86 
88  const std::string &SDKPath,
89  std::string &SDKVersion) {
90  llvm::SmallString<128> IncludePath(SDKPath);
91  llvm::sys::path::append(IncludePath, "Include");
92  SDKVersion = getHighestNumericTupleInDirectory(VFS, IncludePath);
93  return !SDKVersion.empty();
94 }
95 
98  llvm::Optional<llvm::StringRef> WinSdkVersion,
99  llvm::Optional<llvm::StringRef> WinSysRoot, std::string &Path, int &Major,
100  std::string &Version) {
101  if (WinSdkDir || WinSysRoot) {
102  // Don't validate the input; trust the value supplied by the user.
103  // The motivation is to prevent unnecessary file and registry access.
104  llvm::VersionTuple SDKVersion;
105  if (WinSdkVersion)
106  SDKVersion.tryParse(*WinSdkVersion);
107 
108  if (WinSysRoot) {
109  llvm::SmallString<128> SDKPath(*WinSysRoot);
110  llvm::sys::path::append(SDKPath, "Windows Kits");
111  if (!SDKVersion.empty())
112  llvm::sys::path::append(SDKPath, llvm::Twine(SDKVersion.getMajor()));
113  else
115  SDKPath, getHighestNumericTupleInDirectory(VFS, SDKPath));
116  Path = std::string(SDKPath.str());
117  } else {
118  Path = WinSdkDir->str();
119  }
120 
121  if (!SDKVersion.empty()) {
122  Major = SDKVersion.getMajor();
123  Version = SDKVersion.getAsString();
124  } else if (getWindows10SDKVersionFromPath(VFS, Path, Version)) {
125  Major = 10;
126  }
127  return true;
128  }
129  return false;
130 }
131 
132 #ifdef _WIN32
133 static bool readFullStringValue(HKEY hkey, const char *valueName,
134  std::string &value) {
135  std::wstring WideValueName;
136  if (!llvm::ConvertUTF8toWide(valueName, WideValueName))
137  return false;
138 
139  DWORD result = 0;
140  DWORD valueSize = 0;
141  DWORD type = 0;
142  // First just query for the required size.
143  result = RegQueryValueExW(hkey, WideValueName.c_str(), NULL, &type, NULL,
144  &valueSize);
145  if (result != ERROR_SUCCESS || type != REG_SZ || !valueSize)
146  return false;
147  std::vector<BYTE> buffer(valueSize);
148  result = RegQueryValueExW(hkey, WideValueName.c_str(), NULL, NULL, &buffer[0],
149  &valueSize);
150  if (result == ERROR_SUCCESS) {
151  std::wstring WideValue(reinterpret_cast<const wchar_t *>(buffer.data()),
152  valueSize / sizeof(wchar_t));
153  if (valueSize && WideValue.back() == L'\0') {
154  WideValue.pop_back();
155  }
156  // The destination buffer must be empty as an invariant of the conversion
157  // function; but this function is sometimes called in a loop that passes in
158  // the same buffer, however. Simply clear it out so we can overwrite it.
159  value.clear();
160  return llvm::convertWideToUTF8(WideValue, value);
161  }
162  return false;
163 }
164 #endif
165 
166 /// Read registry string.
167 /// This also supports a means to look for high-versioned keys by use
168 /// of a $VERSION placeholder in the key path.
169 /// $VERSION in the key path is a placeholder for the version number,
170 /// causing the highest value path to be searched for and used.
171 /// I.e. "SOFTWARE\\Microsoft\\VisualStudio\\$VERSION".
172 /// There can be additional characters in the component. Only the numeric
173 /// characters are compared. This function only searches HKLM.
174 static bool getSystemRegistryString(const char *keyPath, const char *valueName,
175  std::string &value, std::string *phValue) {
176 #ifndef _WIN32
177  return false;
178 #else
179  HKEY hRootKey = HKEY_LOCAL_MACHINE;
180  HKEY hKey = NULL;
181  long lResult;
182  bool returnValue = false;
183 
184  const char *placeHolder = strstr(keyPath, "$VERSION");
185  std::string bestName;
186  // If we have a $VERSION placeholder, do the highest-version search.
187  if (placeHolder) {
188  const char *keyEnd = placeHolder - 1;
189  const char *nextKey = placeHolder;
190  // Find end of previous key.
191  while ((keyEnd > keyPath) && (*keyEnd != '\\'))
192  keyEnd--;
193  // Find end of key containing $VERSION.
194  while (*nextKey && (*nextKey != '\\'))
195  nextKey++;
196  size_t partialKeyLength = keyEnd - keyPath;
197  char partialKey[256];
198  if (partialKeyLength >= sizeof(partialKey))
199  partialKeyLength = sizeof(partialKey) - 1;
200  strncpy(partialKey, keyPath, partialKeyLength);
201  partialKey[partialKeyLength] = '\0';
202  HKEY hTopKey = NULL;
203  lResult = RegOpenKeyExA(hRootKey, partialKey, 0, KEY_READ | KEY_WOW64_32KEY,
204  &hTopKey);
205  if (lResult == ERROR_SUCCESS) {
206  char keyName[256];
207  double bestValue = 0.0;
208  DWORD index, size = sizeof(keyName) - 1;
209  for (index = 0; RegEnumKeyExA(hTopKey, index, keyName, &size, NULL, NULL,
210  NULL, NULL) == ERROR_SUCCESS;
211  index++) {
212  const char *sp = keyName;
213  while (*sp && !llvm::isDigit(*sp))
214  sp++;
215  if (!*sp)
216  continue;
217  const char *ep = sp + 1;
218  while (*ep && (llvm::isDigit(*ep) || (*ep == '.')))
219  ep++;
220  char numBuf[32];
221  strncpy(numBuf, sp, sizeof(numBuf) - 1);
222  numBuf[sizeof(numBuf) - 1] = '\0';
223  double dvalue = strtod(numBuf, NULL);
224  if (dvalue > bestValue) {
225  // Test that InstallDir is indeed there before keeping this index.
226  // Open the chosen key path remainder.
227  bestName = keyName;
228  // Append rest of key.
229  bestName.append(nextKey);
230  lResult = RegOpenKeyExA(hTopKey, bestName.c_str(), 0,
231  KEY_READ | KEY_WOW64_32KEY, &hKey);
232  if (lResult == ERROR_SUCCESS) {
233  if (readFullStringValue(hKey, valueName, value)) {
234  bestValue = dvalue;
235  if (phValue)
236  *phValue = bestName;
237  returnValue = true;
238  }
239  RegCloseKey(hKey);
240  }
241  }
242  size = sizeof(keyName) - 1;
243  }
244  RegCloseKey(hTopKey);
245  }
246  } else {
247  lResult =
248  RegOpenKeyExA(hRootKey, keyPath, 0, KEY_READ | KEY_WOW64_32KEY, &hKey);
249  if (lResult == ERROR_SUCCESS) {
250  if (readFullStringValue(hKey, valueName, value))
251  returnValue = true;
252  if (phValue)
253  phValue->clear();
254  RegCloseKey(hKey);
255  }
256  }
257  return returnValue;
258 #endif // _WIN32
259 }
260 
261 namespace llvm {
262 
264  switch (Arch) {
266  return "x86";
267  case Triple::ArchType::x86_64:
268  return "x64";
269  case Triple::ArchType::arm:
270  return "arm";
271  case Triple::ArchType::aarch64:
272  return "arm64";
273  default:
274  return "";
275  }
276 }
277 
279  switch (Arch) {
281  // x86 is default in legacy VC toolchains.
282  // e.g. x86 libs are directly in /lib as opposed to /lib/x86.
283  return "";
284  case Triple::ArchType::x86_64:
285  return "amd64";
286  case Triple::ArchType::arm:
287  return "arm";
288  case Triple::ArchType::aarch64:
289  return "arm64";
290  default:
291  return "";
292  }
293 }
294 
296  switch (Arch) {
298  return "i386";
299  case Triple::ArchType::x86_64:
300  return "amd64";
301  case Triple::ArchType::arm:
302  return "arm";
303  case Triple::ArchType::aarch64:
304  return "arm64";
305  default:
306  return "";
307  }
308 }
309 
311  Triple::ArchType Arch, std::string &path) {
312  if (SDKMajor >= 8) {
313  sys::path::append(LibPath, archToWindowsSDKArch(Arch));
314  } else {
315  switch (Arch) {
316  // In Windows SDK 7.x, x86 libraries are directly in the Lib folder.
317  case Triple::x86:
318  break;
319  case Triple::x86_64:
320  sys::path::append(LibPath, "x64");
321  break;
322  case Triple::arm:
323  // It is not necessary to link against Windows SDK 7.x when targeting ARM.
324  return false;
325  default:
326  return false;
327  }
328  }
329 
330  path = std::string(LibPath.str());
331  return true;
332 }
333 
335  const std::string &VCToolChainPath,
336  Triple::ArchType TargetArch,
337  StringRef SubdirParent) {
338  const char *SubdirName;
339  const char *IncludeName;
340  switch (VSLayout) {
342  SubdirName = archToLegacyVCArch(TargetArch);
343  IncludeName = "include";
344  break;
346  SubdirName = archToWindowsSDKArch(TargetArch);
347  IncludeName = "include";
348  break;
350  SubdirName = archToDevDivInternalArch(TargetArch);
351  IncludeName = "inc";
352  break;
353  }
354 
355  SmallString<256> Path(VCToolChainPath);
356  if (!SubdirParent.empty())
357  sys::path::append(Path, SubdirParent);
358 
359  switch (Type) {
361  if (VSLayout == ToolsetLayout::VS2017OrNewer) {
362  // MSVC ships with two linkers: a 32-bit x86 and 64-bit x86 linker.
363  // On x86, pick the linker that corresponds to the current process.
364  // On ARM64, pick the 32-bit x86 linker; the 64-bit one doesn't run
365  // on Windows 10.
366  //
367  // FIXME: Consider using IsWow64GuestMachineSupported to figure out
368  // if we can invoke the 64-bit linker. It's generally preferable
369  // because it won't run out of address-space.
370  const bool HostIsX64 =
372  const char *const HostName = HostIsX64 ? "Hostx64" : "Hostx86";
373  sys::path::append(Path, "bin", HostName, SubdirName);
374  } else { // OlderVS or DevDivInternal
375  sys::path::append(Path, "bin", SubdirName);
376  }
377  break;
379  sys::path::append(Path, IncludeName);
380  break;
382  sys::path::append(Path, "lib", SubdirName);
383  break;
384  }
385  return std::string(Path.str());
386 }
387 
388 bool useUniversalCRT(ToolsetLayout VSLayout, const std::string &VCToolChainPath,
389  Triple::ArchType TargetArch, vfs::FileSystem &VFS) {
391  SubDirectoryType::Include, VSLayout, VCToolChainPath, TargetArch));
392  sys::path::append(TestPath, "stdlib.h");
393  return !VFS.exists(TestPath);
394 }
395 
397  Optional<StringRef> WinSdkVersion,
398  Optional<StringRef> WinSysRoot, std::string &Path,
399  int &Major, std::string &WindowsSDKIncludeVersion,
400  std::string &WindowsSDKLibVersion) {
401  // Trust /winsdkdir and /winsdkversion if present.
402  if (getWindowsSDKDirViaCommandLine(VFS, WinSdkDir, WinSdkVersion, WinSysRoot,
403  Path, Major, WindowsSDKIncludeVersion)) {
404  WindowsSDKLibVersion = WindowsSDKIncludeVersion;
405  return true;
406  }
407 
408  // FIXME: Try env vars (%WindowsSdkDir%, %UCRTVersion%) before going to
409  // registry.
410 
411  // Try the Windows registry.
412  std::string RegistrySDKVersion;
414  "SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\$VERSION",
415  "InstallationFolder", Path, &RegistrySDKVersion))
416  return false;
417  if (Path.empty() || RegistrySDKVersion.empty())
418  return false;
419 
420  WindowsSDKIncludeVersion.clear();
421  WindowsSDKLibVersion.clear();
422  Major = 0;
423  std::sscanf(RegistrySDKVersion.c_str(), "v%d.", &Major);
424  if (Major <= 7)
425  return true;
426  if (Major == 8) {
427  // Windows SDK 8.x installs libraries in a folder whose names depend on the
428  // version of the OS you're targeting. By default choose the newest, which
429  // usually corresponds to the version of the OS you've installed the SDK on.
430  const char *Tests[] = {"winv6.3", "win8", "win7"};
431  for (const char *Test : Tests) {
432  SmallString<128> TestPath(Path);
433  sys::path::append(TestPath, "Lib", Test);
434  if (VFS.exists(TestPath)) {
435  WindowsSDKLibVersion = Test;
436  break;
437  }
438  }
439  return !WindowsSDKLibVersion.empty();
440  }
441  if (Major == 10) {
442  if (!getWindows10SDKVersionFromPath(VFS, Path, WindowsSDKIncludeVersion))
443  return false;
444  WindowsSDKLibVersion = WindowsSDKIncludeVersion;
445  return true;
446  }
447  // Unsupported SDK version
448  return false;
449 }
450 
452  Optional<StringRef> WinSdkVersion,
453  Optional<StringRef> WinSysRoot, std::string &Path,
454  std::string &UCRTVersion) {
455  // If /winsdkdir is passed, use it as location for the UCRT too.
456  // FIXME: Should there be a dedicated /ucrtdir to override /winsdkdir?
457  int Major;
458  if (getWindowsSDKDirViaCommandLine(VFS, WinSdkDir, WinSdkVersion, WinSysRoot,
459  Path, Major, UCRTVersion))
460  return true;
461 
462  // FIXME: Try env vars (%UniversalCRTSdkDir%, %UCRTVersion%) before going to
463  // registry.
464 
465  // vcvarsqueryregistry.bat for Visual Studio 2015 queries the registry
466  // for the specific key "KitsRoot10". So do we.
468  "SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots", "KitsRoot10",
469  Path, nullptr))
470  return false;
471 
472  return getWindows10SDKVersionFromPath(VFS, Path, UCRTVersion);
473 }
474 
476  Optional<StringRef> VCToolsDir,
477  Optional<StringRef> VCToolsVersion,
478  Optional<StringRef> WinSysRoot,
479  std::string &Path, ToolsetLayout &VSLayout) {
480  // Don't validate the input; trust the value supplied by the user.
481  // The primary motivation is to prevent unnecessary file and registry access.
482  if (VCToolsDir || WinSysRoot) {
483  if (WinSysRoot) {
484  SmallString<128> ToolsPath(*WinSysRoot);
485  sys::path::append(ToolsPath, "VC", "Tools", "MSVC");
486  std::string ToolsVersion;
487  if (VCToolsVersion)
488  ToolsVersion = VCToolsVersion->str();
489  else
490  ToolsVersion = getHighestNumericTupleInDirectory(VFS, ToolsPath);
491  sys::path::append(ToolsPath, ToolsVersion);
492  Path = std::string(ToolsPath.str());
493  } else {
494  Path = VCToolsDir->str();
495  }
496  VSLayout = ToolsetLayout::VS2017OrNewer;
497  return true;
498  }
499  return false;
500 }
501 
502 bool findVCToolChainViaEnvironment(vfs::FileSystem &VFS, std::string &Path,
503  ToolsetLayout &VSLayout) {
504  // These variables are typically set by vcvarsall.bat
505  // when launching a developer command prompt.
506  if (Optional<std::string> VCToolsInstallDir =
507  sys::Process::GetEnv("VCToolsInstallDir")) {
508  // This is only set by newer Visual Studios, and it leads straight to
509  // the toolchain directory.
510  Path = std::move(*VCToolsInstallDir);
511  VSLayout = ToolsetLayout::VS2017OrNewer;
512  return true;
513  }
514  if (Optional<std::string> VCInstallDir =
515  sys::Process::GetEnv("VCINSTALLDIR")) {
516  // If the previous variable isn't set but this one is, then we've found
517  // an older Visual Studio. This variable is set by newer Visual Studios too,
518  // so this check has to appear second.
519  // In older Visual Studios, the VC directory is the toolchain.
520  Path = std::move(*VCInstallDir);
521  VSLayout = ToolsetLayout::OlderVS;
522  return true;
523  }
524 
525  // We couldn't find any VC environment variables. Let's walk through PATH and
526  // see if it leads us to a VC toolchain bin directory. If it does, pick the
527  // first one that we find.
528  if (Optional<std::string> PathEnv = sys::Process::GetEnv("PATH")) {
529  SmallVector<StringRef, 8> PathEntries;
530  StringRef(*PathEnv).split(PathEntries, sys::EnvPathSeparator);
531  for (StringRef PathEntry : PathEntries) {
532  if (PathEntry.empty())
533  continue;
534 
535  SmallString<256> ExeTestPath;
536 
537  // If cl.exe doesn't exist, then this definitely isn't a VC toolchain.
538  ExeTestPath = PathEntry;
539  sys::path::append(ExeTestPath, "cl.exe");
540  if (!VFS.exists(ExeTestPath))
541  continue;
542 
543  // cl.exe existing isn't a conclusive test for a VC toolchain; clang also
544  // has a cl.exe. So let's check for link.exe too.
545  ExeTestPath = PathEntry;
546  sys::path::append(ExeTestPath, "link.exe");
547  if (!VFS.exists(ExeTestPath))
548  continue;
549 
550  // whatever/VC/bin --> old toolchain, VC dir is toolchain dir.
551  StringRef TestPath = PathEntry;
552  bool IsBin = sys::path::filename(TestPath).equals_insensitive("bin");
553  if (!IsBin) {
554  // Strip any architecture subdir like "amd64".
555  TestPath = sys::path::parent_path(TestPath);
556  IsBin = sys::path::filename(TestPath).equals_insensitive("bin");
557  }
558  if (IsBin) {
559  StringRef ParentPath = sys::path::parent_path(TestPath);
560  StringRef ParentFilename = sys::path::filename(ParentPath);
561  if (ParentFilename.equals_insensitive("VC")) {
562  Path = std::string(ParentPath);
563  VSLayout = ToolsetLayout::OlderVS;
564  return true;
565  }
566  if (ParentFilename.equals_insensitive("x86ret") ||
567  ParentFilename.equals_insensitive("x86chk") ||
568  ParentFilename.equals_insensitive("amd64ret") ||
569  ParentFilename.equals_insensitive("amd64chk")) {
570  Path = std::string(ParentPath);
572  return true;
573  }
574 
575  } else {
576  // This could be a new (>=VS2017) toolchain. If it is, we should find
577  // path components with these prefixes when walking backwards through
578  // the path.
579  // Note: empty strings match anything.
580  StringRef ExpectedPrefixes[] = {"", "Host", "bin", "",
581  "MSVC", "Tools", "VC"};
582 
583  auto It = sys::path::rbegin(PathEntry);
584  auto End = sys::path::rend(PathEntry);
585  for (StringRef Prefix : ExpectedPrefixes) {
586  if (It == End)
587  goto NotAToolChain;
588  if (!It->startswith_insensitive(Prefix))
589  goto NotAToolChain;
590  ++It;
591  }
592 
593  // We've found a new toolchain!
594  // Back up 3 times (/bin/Host/arch) to get the root path.
595  StringRef ToolChainPath(PathEntry);
596  for (int i = 0; i < 3; ++i)
597  ToolChainPath = sys::path::parent_path(ToolChainPath);
598 
599  Path = std::string(ToolChainPath);
600  VSLayout = ToolsetLayout::VS2017OrNewer;
601  return true;
602  }
603 
604  NotAToolChain:
605  continue;
606  }
607  }
608  return false;
609 }
610 
611 bool findVCToolChainViaSetupConfig(vfs::FileSystem &VFS, std::string &Path,
612  ToolsetLayout &VSLayout) {
613 #if !defined(USE_MSVC_SETUP_API)
614  return false;
615 #else
616  // FIXME: This really should be done once in the top-level program's main
617  // function, as it may have already been initialized with a different
618  // threading model otherwise.
620  HRESULT HR;
621 
622  // _com_ptr_t will throw a _com_error if a COM calls fail.
623  // The LLVM coding standards forbid exception handling, so we'll have to
624  // stop them from being thrown in the first place.
625  // The destructor will put the regular error handler back when we leave
626  // this scope.
627  struct SuppressCOMErrorsRAII {
628  static void __stdcall handler(HRESULT hr, IErrorInfo *perrinfo) {}
629 
630  SuppressCOMErrorsRAII() { _set_com_error_handler(handler); }
631 
632  ~SuppressCOMErrorsRAII() { _set_com_error_handler(_com_raise_error); }
633 
634  } COMErrorSuppressor;
635 
636  ISetupConfigurationPtr Query;
637  HR = Query.CreateInstance(__uuidof(SetupConfiguration));
638  if (FAILED(HR))
639  return false;
640 
641  IEnumSetupInstancesPtr EnumInstances;
642  HR = ISetupConfiguration2Ptr(Query)->EnumAllInstances(&EnumInstances);
643  if (FAILED(HR))
644  return false;
645 
646  ISetupInstancePtr Instance;
647  HR = EnumInstances->Next(1, &Instance, nullptr);
648  if (HR != S_OK)
649  return false;
650 
651  ISetupInstancePtr NewestInstance;
652  Optional<uint64_t> NewestVersionNum;
653  do {
654  bstr_t VersionString;
655  uint64_t VersionNum;
656  HR = Instance->GetInstallationVersion(VersionString.GetAddress());
657  if (FAILED(HR))
658  continue;
659  HR = ISetupHelperPtr(Query)->ParseVersion(VersionString, &VersionNum);
660  if (FAILED(HR))
661  continue;
662  if (!NewestVersionNum || (VersionNum > NewestVersionNum)) {
663  NewestInstance = Instance;
664  NewestVersionNum = VersionNum;
665  }
666  } while ((HR = EnumInstances->Next(1, &Instance, nullptr)) == S_OK);
667 
668  if (!NewestInstance)
669  return false;
670 
671  bstr_t VCPathWide;
672  HR = NewestInstance->ResolvePath(L"VC", VCPathWide.GetAddress());
673  if (FAILED(HR))
674  return false;
675 
676  std::string VCRootPath;
677  convertWideToUTF8(std::wstring(VCPathWide), VCRootPath);
678 
679  SmallString<256> ToolsVersionFilePath(VCRootPath);
680  sys::path::append(ToolsVersionFilePath, "Auxiliary", "Build",
681  "Microsoft.VCToolsVersion.default.txt");
682 
683  auto ToolsVersionFile = MemoryBuffer::getFile(ToolsVersionFilePath);
684  if (!ToolsVersionFile)
685  return false;
686 
687  SmallString<256> ToolchainPath(VCRootPath);
688  sys::path::append(ToolchainPath, "Tools", "MSVC",
689  ToolsVersionFile->get()->getBuffer().rtrim());
690  auto Status = VFS.status(ToolchainPath);
691  if (!Status || !Status->isDirectory())
692  return false;
693 
694  Path = std::string(ToolchainPath.str());
695  VSLayout = ToolsetLayout::VS2017OrNewer;
696  return true;
697 #endif
698 }
699 
700 bool findVCToolChainViaRegistry(std::string &Path, ToolsetLayout &VSLayout) {
701  std::string VSInstallPath;
702  if (getSystemRegistryString(R"(SOFTWARE\Microsoft\VisualStudio\$VERSION)",
703  "InstallDir", VSInstallPath, nullptr) ||
704  getSystemRegistryString(R"(SOFTWARE\Microsoft\VCExpress\$VERSION)",
705  "InstallDir", VSInstallPath, nullptr)) {
706  if (!VSInstallPath.empty()) {
707  SmallString<256> VCPath(StringRef(VSInstallPath.c_str(),
708  VSInstallPath.find(R"(\Common7\IDE)")));
709  sys::path::append(VCPath, "VC");
710 
711  Path = std::string(VCPath.str());
712  VSLayout = ToolsetLayout::OlderVS;
713  return true;
714  }
715  }
716  return false;
717 }
718 
719 } // namespace llvm
i
i
Definition: README.txt:29
llvm::vfs::FileSystem::dir_begin
virtual directory_iterator dir_begin(const Twine &Dir, std::error_code &EC)=0
Get a directory_iterator for Dir.
IEnumSetupInstances
struct IEnumSetupInstances IEnumSetupInstances
Definition: MSVCSetupApi.h:92
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::VersionTuple::tryParse
bool tryParse(StringRef string)
Try to parse the given string as a version number.
Definition: VersionTuple.cpp:63
llvm::appendArchToWindowsSDKLibPath
bool appendArchToWindowsSDKLibPath(int SDKMajor, llvm::SmallString< 128 > LibPath, llvm::Triple::ArchType Arch, std::string &path)
Definition: MSVCPaths.cpp:310
Optional.h
llvm::archToLegacyVCArch
const char * archToLegacyVCArch(llvm::Triple::ArchType Arch)
Definition: MSVCPaths.cpp:278
llvm::sys::path::rbegin
reverse_iterator rbegin(StringRef path, Style style=Style::native)
Get reverse begin iterator over path.
Definition: Path.cpp:297
llvm::cl::Prefix
@ Prefix
Definition: CommandLine.h:161
llvm::getSubDirectoryPath
std::string getSubDirectoryPath(SubDirectoryType Type, ToolsetLayout VSLayout, const std::string &VCToolChainPath, llvm::Triple::ArchType TargetArch, llvm::StringRef SubdirParent="")
Definition: MSVCPaths.cpp:334
StringRef.h
llvm::Triple::x86
@ x86
Definition: Triple.h:85
Host.h
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1199
Path.h
llvm::ToolsetLayout::OlderVS
@ OlderVS
VersionTuple.h
llvm::findVCToolChainViaCommandLine
bool findVCToolChainViaCommandLine(vfs::FileSystem &VFS, llvm::Optional< llvm::StringRef > VCToolsDir, llvm::Optional< llvm::StringRef > VCToolsVersion, llvm::Optional< llvm::StringRef > WinSysRoot, std::string &Path, ToolsetLayout &VSLayout)
Definition: MSVCPaths.cpp:475
llvm::sys::COMThreadingMode::SingleThreaded
@ SingleThreaded
llvm::Triple
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
llvm::vfs::FileSystem::status
virtual llvm::ErrorOr< Status > status(const Twine &Path)=0
Get the status of the entry at Path, if one exists.
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
llvm::Triple::x86_64
@ x86_64
Definition: Triple.h:86
llvm::vfs::directory_iterator
An input iterator over the entries in a virtual path, similar to llvm::sys::fs::directory_iterator.
Definition: VirtualFileSystem.h:182
llvm::Optional< llvm::StringRef >
llvm::getUniversalCRTSdkDir
bool getUniversalCRTSdkDir(vfs::FileSystem &VFS, llvm::Optional< llvm::StringRef > WinSdkDir, llvm::Optional< llvm::StringRef > WinSdkVersion, llvm::Optional< llvm::StringRef > WinSysRoot, std::string &Path, std::string &UCRTVersion)
Definition: MSVCPaths.cpp:451
llvm::ToolsetLayout::DevDivInternal
@ DevDivInternal
x86
Note that only the low bits of effective_addr2 are used On bit we don t eliminate the computation of the top half of effective_addr2 because we don t have whole function selection dags On x86
Definition: README.txt:318
MSVCSetupApi.h
llvm::MemoryBuffer::getFile
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, bool IsVolatile=false, Optional< Align > Alignment=None)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...
Definition: MemoryBuffer.cpp:244
llvm::VersionTuple::getMajor
unsigned getMajor() const
Retrieve the major version number.
Definition: VersionTuple.h:72
ISetupInstance2
struct ISetupInstance2 ISetupInstance2
Definition: MSVCSetupApi.h:87
llvm::SubDirectoryType::Bin
@ Bin
result
It looks like we only need to define PPCfmarto for these because according to these instructions perform RTO on fma s result
Definition: README_P9.txt:256
llvm::sys::path::append
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
Definition: Path.cpp:456
Process.h
llvm::sys::EnvPathSeparator
const char EnvPathSeparator
This is the OS-specific separator for PATH like environment variables:
Definition: Program.h:32
llvm::findVCToolChainViaRegistry
bool findVCToolChainViaRegistry(std::string &Path, ToolsetLayout &VSLayout)
Definition: MSVCPaths.cpp:700
llvm::Triple::ArchType
ArchType
Definition: Triple.h:46
llvm::PGSOQueryType::Test
@ Test
SmallString.h
COM.h
Twine.h
llvm::SubDirectoryType::Lib
@ Lib
llvm::findVCToolChainViaSetupConfig
bool findVCToolChainViaSetupConfig(vfs::FileSystem &VFS, std::string &Path, ToolsetLayout &VSLayout)
Definition: MSVCPaths.cpp:611
llvm::MipsISD::Highest
@ Highest
Definition: MipsISelLowering.h:68
llvm::vfs::FileSystem::exists
bool exists(const Twine &Path)
Check whether a file exists. Provided for convenience.
Definition: VirtualFileSystem.cpp:150
llvm::VersionTuple
Represents a version number in the form major[.minor[.subminor[.build]]].
Definition: VersionTuple.h:31
llvm::IndexedInstrProf::Version
const uint64_t Version
Definition: InstrProf.h:1056
llvm::Triple::getArch
ArchType getArch() const
Get the parsed architecture type of this triple.
Definition: Triple.h:354
llvm::findVCToolChainViaEnvironment
bool findVCToolChainViaEnvironment(vfs::FileSystem &VFS, std::string &Path, ToolsetLayout &VSLayout)
Definition: MSVCPaths.cpp:502
llvm::SmallString< 128 >
llvm::StringRef::empty
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:134
MSVCPaths.h
getWindowsSDKDirViaCommandLine
static bool getWindowsSDKDirViaCommandLine(llvm::vfs::FileSystem &VFS, llvm::Optional< llvm::StringRef > WinSdkDir, llvm::Optional< llvm::StringRef > WinSdkVersion, llvm::Optional< llvm::StringRef > WinSysRoot, std::string &Path, int &Major, std::string &Version)
Definition: MSVCPaths.cpp:96
type
AMD64 Optimization Manual has some nice information about optimizing integer multiplication by a constant How much of it applies to Intel s X86 implementation There are definite trade offs to xmm0 cvttss2siq rdx jb L3 subss xmm0 rax cvttss2siq rdx xorq rdx rax ret instead of xmm1 cvttss2siq rcx movaps xmm2 subss xmm2 cvttss2siq rax rdx xorq rax ucomiss xmm0 cmovb rax ret Seems like the jb branch has high likelihood of being taken It would have saved a few instructions It s not possible to reference and DH registers in an instruction requiring REX prefix divb and mulb both produce results in AH If isel emits a CopyFromReg which gets turned into a movb and that can be allocated a r8b r15b To get around isel emits a CopyFromReg from AX and then right shift it down by and truncate it It s not pretty but it works We need some register allocation magic to make the hack go which would often require a callee saved register Callees usually need to keep this value live for most of their body so it doesn t add a significant burden on them We currently implement this in however this is suboptimal because it means that it would be quite awkward to implement the optimization for callers A better implementation would be to relax the LLVM IR rules for sret arguments to allow a function with an sret argument to have a non void return type
Definition: README-X86-64.txt:70
llvm::ToolsetLayout::VS2017OrNewer
@ VS2017OrNewer
ISetupConfiguration
struct ISetupConfiguration ISetupConfiguration
Definition: MSVCSetupApi.h:97
llvm::ToolsetLayout
ToolsetLayout
Definition: MSVCPaths.h:30
index
splat index
Definition: README_ALTIVEC.txt:181
uint64_t
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
ISetupConfiguration2
struct ISetupConfiguration2 ISetupConfiguration2
Definition: MSVCSetupApi.h:102
ISetupInstance
struct ISetupInstance ISetupInstance
Definition: MSVCSetupApi.h:82
size
i< reg-> size
Definition: README.txt:166
llvm::AMDGPU::SDWA::DWORD
@ DWORD
Definition: SIDefines.h:772
llvm::sys::path::parent_path
StringRef parent_path(StringRef path, Style style=Style::native)
Get parent path.
Definition: Path.cpp:467
llvm::sys::Process::GetEnv
static Optional< std::string > GetEnv(StringRef name)
getSystemRegistryString
static bool getSystemRegistryString(const char *keyPath, const char *valueName, std::string &value, std::string *phValue)
Read registry string.
Definition: MSVCPaths.cpp:174
llvm::getWindowsSDKDir
bool getWindowsSDKDir(vfs::FileSystem &VFS, llvm::Optional< llvm::StringRef > WinSdkDir, llvm::Optional< llvm::StringRef > WinSdkVersion, llvm::Optional< llvm::StringRef > WinSysRoot, std::string &Path, int &Major, std::string &WindowsSDKIncludeVersion, std::string &WindowsSDKLibVersion)
Get Windows SDK installation directory.
Definition: MSVCPaths.cpp:396
Status
Definition: SIModeRegister.cpp:29
Triple.h
isDigit
static bool isDigit(const char C)
Definition: RustDemangle.cpp:173
llvm::Triple::arm
@ arm
Definition: Triple.h:49
getWindows10SDKVersionFromPath
static bool getWindows10SDKVersionFromPath(llvm::vfs::FileSystem &VFS, const std::string &SDKPath, std::string &SDKVersion)
Definition: MSVCPaths.cpp:87
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
llvm::convertWideToUTF8
bool convertWideToUTF8(const std::wstring &Source, std::string &Result)
Converts a std::wstring to a UTF-8 encoded std::string.
Definition: ConvertUTFWrapper.cpp:271
VirtualFileSystem.h
ConvertUTF.h
sp
_bar sp
Definition: README.txt:151
llvm::SubDirectoryType::Include
@ Include
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
llvm::archToWindowsSDKArch
const char * archToWindowsSDKArch(llvm::Triple::ArchType Arch)
Definition: MSVCPaths.cpp:263
llvm::vfs::FileSystem
The virtual file system interface.
Definition: VirtualFileSystem.h:268
llvm::sys::InitializeCOMRAII
Definition: COM.h:22
llvm::VersionTuple::getAsString
std::string getAsString() const
Retrieve a string representation of the version number.
Definition: VersionTuple.cpp:21
llvm::sys::getProcessTriple
std::string getProcessTriple()
getProcessTriple() - Return an appropriate target triple for generating code to be loaded into the cu...
Definition: Host.cpp:1961
llvm::SubDirectoryType
SubDirectoryType
Definition: MSVCPaths.h:24
llvm::SmallString::str
StringRef str() const
Explicit conversion to StringRef.
Definition: SmallString.h:260
llvm::StringRef::equals_insensitive
bool equals_insensitive(StringRef RHS) const
Check for string equality, ignoring case.
Definition: StringRef.h:170
llvm::sys::path::filename
StringRef filename(StringRef path, Style style=Style::native)
Get filename.
Definition: Path.cpp:577
SmallVector.h
llvm::ConvertUTF8toWide
bool ConvertUTF8toWide(unsigned WideCharWidth, llvm::StringRef Source, char *&ResultPtr, const UTF8 *&ErrorPtr)
Convert an UTF8 StringRef to UTF8, UTF16, or UTF32 depending on WideCharWidth.
Definition: ConvertUTFWrapper.cpp:19
Program.h
getHighestNumericTupleInDirectory
static std::string getHighestNumericTupleInDirectory(llvm::vfs::FileSystem &VFS, llvm::StringRef Directory)
Definition: MSVCPaths.cpp:62
llvm::VersionTuple::empty
bool empty() const
Determine whether this version information is empty (e.g., all version components are zero).
Definition: VersionTuple.h:67
llvm::sys::path::rend
reverse_iterator rend(StringRef path)
Get reverse end iterator over path.
Definition: Path.cpp:306
llvm::StringRef::str
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:221
ISetupHelper
struct ISetupHelper ISetupHelper
Definition: MSVCSetupApi.h:112
llvm::archToDevDivInternalArch
const char * archToDevDivInternalArch(llvm::Triple::ArchType Arch)
Definition: MSVCPaths.cpp:295
llvm::useUniversalCRT
bool useUniversalCRT(ToolsetLayout VSLayout, const std::string &VCToolChainPath, llvm::Triple::ArchType TargetArch, llvm::vfs::FileSystem &VFS)
Definition: MSVCPaths.cpp:388
llvm::StringRef::split
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition: StringRef.h:692