blob: 46eef21905d4971764ae979c50d441382a1cd1dc [file] [log] [blame]
Chandler Carruth1fc603e2011-12-17 23:10:01 +00001//===--- 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"
David Majnemere11d3732015-06-08 00:22:46 +000011#include "Tools.h"
Jordan Rosea7d03842013-02-08 22:30:41 +000012#include "clang/Basic/CharInfo.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000013#include "clang/Basic/Version.h"
Chandler Carruth1fc603e2011-12-17 23:10:01 +000014#include "clang/Driver/Compilation.h"
15#include "clang/Driver/Driver.h"
Rafael Espindola79764462013-03-24 15:06:53 +000016#include "clang/Driver/DriverDiagnostic.h"
Chandler Carruth1fc603e2011-12-17 23:10:01 +000017#include "clang/Driver/Options.h"
Zachary Turner0eaf8fc2014-10-22 20:40:28 +000018#include "llvm/ADT/StringExtras.h"
David L. Jones24fb20c2016-12-07 23:41:58 +000019#include "llvm/ADT/StringSwitch.h"
Alp Tokerf1ffc842014-06-22 04:31:15 +000020#include "llvm/Config/llvm-config.h"
Reid Kleckner898229a2013-06-14 17:17:23 +000021#include "llvm/Option/Arg.h"
22#include "llvm/Option/ArgList.h"
Adrian McCarthye4b26fc2016-05-13 23:20:11 +000023#include "llvm/Support/ConvertUTF.h"
Chandler Carruth1fc603e2011-12-17 23:10:01 +000024#include "llvm/Support/ErrorHandling.h"
Zachary Turner0eaf8fc2014-10-22 20:40:28 +000025#include "llvm/Support/FileSystem.h"
Reid Kleckner723fabf2017-02-02 19:29:46 +000026#include "llvm/Support/Host.h"
Mehdi Amini9670f842016-07-18 19:02:11 +000027#include "llvm/Support/Path.h"
Zachary Turner0eaf8fc2014-10-22 20:40:28 +000028#include "llvm/Support/Process.h"
Reid Kleckner6b7156b2015-01-23 19:16:25 +000029#include <cstdio>
30
Alp Tokerf1ffc842014-06-22 04:31:15 +000031#if defined(LLVM_ON_WIN32)
Reid Kleckner723fabf2017-02-02 19:29:46 +000032 #define USE_WIN32
33
34 // FIXME: Make this configurable with cmake when the final version of the API
35 // has been released.
36 #if 0
37 #define USE_VS_SETUP_CONFIG
38 #endif
Alp Tokerfcce1832014-06-22 03:27:45 +000039#endif
40
Reid Kleckner723fabf2017-02-02 19:29:46 +000041// Include the necessary headers to interface with the Windows registry and
42// environment.
Alp Tokerfcce1832014-06-22 03:27:45 +000043#ifdef USE_WIN32
Chandler Carruth1fc603e2011-12-17 23:10:01 +000044 #define WIN32_LEAN_AND_MEAN
45 #define NOGDI
Yaron Keren7fc6f1e2014-12-04 21:46:50 +000046 #ifndef NOMINMAX
47 #define NOMINMAX
48 #endif
Logan Chien733e3c62014-06-24 16:18:10 +000049 #include <windows.h>
Chandler Carruth1fc603e2011-12-17 23:10:01 +000050#endif
51
Reid Kleckner723fabf2017-02-02 19:29:46 +000052// Include the headers needed for the setup config COM stuff and define
53// smart pointers for the interfaces we need.
54#ifdef USE_VS_SETUP_CONFIG
55 #include "clang/Basic/VirtualFileSystem.h"
56 #include "llvm/Support/COM.h"
57 #include <comdef.h>
58 #include <Setup.Configuration.h>
59 _COM_SMARTPTR_TYPEDEF(ISetupConfiguration, __uuidof(ISetupConfiguration));
60 _COM_SMARTPTR_TYPEDEF(ISetupConfiguration2, __uuidof(ISetupConfiguration2));
61 _COM_SMARTPTR_TYPEDEF(ISetupHelper, __uuidof(ISetupHelper));
62 _COM_SMARTPTR_TYPEDEF(IEnumSetupInstances, __uuidof(IEnumSetupInstances));
63 _COM_SMARTPTR_TYPEDEF(ISetupInstance, __uuidof(ISetupInstance));
64 _COM_SMARTPTR_TYPEDEF(ISetupInstance2, __uuidof(ISetupInstance2));
65#endif
66
Chandler Carruth1fc603e2011-12-17 23:10:01 +000067using namespace clang::driver;
68using namespace clang::driver::toolchains;
69using namespace clang;
Reid Kleckner898229a2013-06-14 17:17:23 +000070using namespace llvm::opt;
Chandler Carruth1fc603e2011-12-17 23:10:01 +000071
Reid Kleckner723fabf2017-02-02 19:29:46 +000072// Defined below.
73// Forward declare this so there aren't too many things above the constructor.
74static bool getSystemRegistryString(const char *keyPath, const char *valueName,
75 std::string &value, std::string *phValue);
76
77// Check various environment variables to try and find a toolchain.
78static bool findVCToolChainViaEnvironment(std::string &Path,
79 bool &IsVS2017OrNewer) {
80 // These variables are typically set by vcvarsall.bat
81 // when launching a developer command prompt.
82 if (llvm::Optional<std::string> VCToolsInstallDir =
83 llvm::sys::Process::GetEnv("VCToolsInstallDir")) {
84 // This is only set by newer Visual Studios, and it leads straight to
85 // the toolchain directory.
86 Path = std::move(*VCToolsInstallDir);
87 IsVS2017OrNewer = true;
88 return true;
89 }
90 if (llvm::Optional<std::string> VCInstallDir =
91 llvm::sys::Process::GetEnv("VCINSTALLDIR")) {
92 // If the previous variable isn't set but this one is, then we've found
93 // an older Visual Studio. This variable is set by newer Visual Studios too,
94 // so this check has to appear second.
95 // In older Visual Studios, the VC directory is the toolchain.
96 Path = std::move(*VCInstallDir);
97 IsVS2017OrNewer = false;
98 return true;
99 }
100
101 // We couldn't find any VC environment variables. Let's walk through PATH and
102 // see if it leads us to a VC toolchain bin directory. If it does, pick the
103 // first one that we find.
104 if (llvm::Optional<std::string> PathEnv =
105 llvm::sys::Process::GetEnv("PATH")) {
106 llvm::SmallVector<llvm::StringRef, 8> PathEntries;
107 llvm::StringRef(*PathEnv).split(PathEntries, llvm::sys::EnvPathSeparator);
108 for (llvm::StringRef PathEntry : PathEntries) {
109 if (PathEntry.empty())
110 continue;
111
112 llvm::SmallString<256> ExeTestPath;
113
114 // If cl.exe doesn't exist, then this definitely isn't a VC toolchain.
115 ExeTestPath = PathEntry;
116 llvm::sys::path::append(ExeTestPath, "cl.exe");
117 if (!llvm::sys::fs::exists(ExeTestPath))
118 continue;
119
120 // cl.exe existing isn't a conclusive test for a VC toolchain; clang also
121 // has a cl.exe. So let's check for link.exe too.
122 ExeTestPath = PathEntry;
123 llvm::sys::path::append(ExeTestPath, "link.exe");
124 if (!llvm::sys::fs::exists(ExeTestPath))
125 continue;
126
127 // whatever/VC/bin --> old toolchain, VC dir is toolchain dir.
128 if (llvm::sys::path::filename(PathEntry) == "bin") {
129 llvm::StringRef ParentPath = llvm::sys::path::parent_path(PathEntry);
130 if (llvm::sys::path::filename(ParentPath) == "VC") {
131 Path = ParentPath;
132 IsVS2017OrNewer = false;
133 return true;
134 }
135 } else {
136 // This could be a new (>=VS2017) toolchain. If it is, we should find
137 // path components with these prefixes when walking backwards through
138 // the path.
139 // Note: empty strings match anything.
140 llvm::StringRef ExpectedPrefixes[] =
141 { "", "Host", "bin", "", "MSVC", "Tools", "VC" };
142
143 llvm::sys::path::reverse_iterator
144 It = llvm::sys::path::rbegin(PathEntry),
145 End = llvm::sys::path::rend(PathEntry);
146 for (llvm::StringRef Prefix : ExpectedPrefixes) {
147 if (It == End) goto NotAToolChain;
148 if (!It->startswith(Prefix)) goto NotAToolChain;
149 ++It;
150 }
151
152 // We've found a new toolchain!
153 // Back up 3 times (/bin/Host/arch) to get the root path.
154 llvm::StringRef ToolChainPath(PathEntry);
155 for (int i = 0; i < 3; ++i)
156 ToolChainPath = llvm::sys::path::parent_path(ToolChainPath);
157
158 Path = ToolChainPath;
159 IsVS2017OrNewer = true;
160 return true;
161 }
162
163 NotAToolChain:
164 continue;
165 }
166 }
167 return false;
168}
169
170// Query the Setup Config server for installs, then pick the newest version
171// and find its default VC toolchain.
172// This is the preferred way to discover new Visual Studios, as they're no
173// longer listed in the registry.
174static bool findVCToolChainViaSetupConfig(std::string &Path,
175 bool &IsVS2017OrNewer) {
176#ifndef USE_VS_SETUP_CONFIG
177 return false;
178#else
179 llvm::sys::InitializeCOMRAII COM(llvm::sys::COMThreadingMode::SingleThreaded);
180 HRESULT HR;
181
182 // _com_ptr_t will throw a _com_error if a COM calls fail.
183 // The LLVM coding standards forbid exception handling, so we'll have to
184 // stop them from being thrown in the first place.
185 // The destructor will put the regular error handler back when we leave
186 // this scope.
187 struct SuppressCOMErrorsRAII {
188 SuppressCOMErrorsRAII() {
189 _set_com_error_handler([](HRESULT, IErrorInfo *) { });
190 }
191 ~SuppressCOMErrorsRAII() {
192 _set_com_error_handler(_com_raise_error);
193 }
194 } COMErrorSuppressor;
195
196 ISetupConfigurationPtr Query;
197 HR = Query.CreateInstance(__uuidof(SetupConfiguration));
198 if (FAILED(HR)) return false;
199
200 IEnumSetupInstancesPtr EnumInstances;
201 HR = ISetupConfiguration2Ptr(Query)->EnumAllInstances(&EnumInstances);
202 if (FAILED(HR)) return false;
203
204 ISetupInstancePtr Instance;
205 HR = EnumInstances->Next(1, &Instance, nullptr);
206 if (HR != S_OK) return false;
207
208 ISetupInstancePtr NewestInstance(Instance);
209 uint64_t NewestVersionNum;
210 {
211 bstr_t VersionString;
212 HR = NewestInstance->GetInstallationVersion(VersionString.GetAddress());
213 if (FAILED(HR)) return false;
214 HR = ISetupHelperPtr(Query)->ParseVersion(VersionString,
215 &NewestVersionNum);
216 if (FAILED(HR)) return false;
217 }
218
219 while ((HR = EnumInstances->Next(1, &Instance, nullptr)) == S_OK) {
220 bstr_t VersionString;
221 uint64_t VersionNum;
222 HR = Instance->GetInstallationVersion(VersionString.GetAddress());
223 if (FAILED(HR)) continue;
224 HR = ISetupHelperPtr(Query)->ParseVersion(VersionString,
225 &VersionNum);
226 if (FAILED(HR)) continue;
227 if (VersionNum > NewestVersionNum) {
228 NewestInstance = Instance;
229 NewestVersionNum = VersionNum;
230 }
231 }
232
233 bstr_t VCPathWide;
234 HR = NewestInstance->ResolvePath(L"VC",
235 VCPathWide.GetAddress());
236 if (FAILED(HR)) return false;
237
238 std::string VCRootPath;
239 llvm::convertWideToUTF8(std::wstring(VCPathWide), VCRootPath);
240
241 llvm::SmallString<256> ToolsVersionFilePath(VCRootPath);
242 llvm::sys::path::append(ToolsVersionFilePath,
243 "Auxiliary",
244 "Build",
245 "Microsoft.VCToolsVersion.default.txt");
246
247 auto ToolsVersionFile =
248 clang::vfs::getRealFileSystem()->getBufferForFile(ToolsVersionFilePath);
249 if (!ToolsVersionFile)
250 return false;
251
252 llvm::SmallString<256> ToolchainPath(VCRootPath);
253 llvm::sys::path::append(ToolchainPath,
254 "Tools",
255 "MSVC",
256 ToolsVersionFile->get()->getBuffer().rtrim());
257 if (!llvm::sys::fs::is_directory(ToolchainPath))
258 return false;
259
260 Path = ToolchainPath.str();
261 IsVS2017OrNewer = true;
262 return true;
263#endif /*USE_VS_SETUP_CONFIG*/
264}
265
266// Look in the registry for Visual Studio installs, and use that to get
267// a toolchain path. VS2017 and newer don't get added to the registry.
268// So if we find something here, we know that it's an older version.
269static bool findVCToolChainViaRegistry(std::string &Path,
270 bool &IsVS2017OrNewer) {
271 std::string VSInstallPath;
272 if (getSystemRegistryString(R"(SOFTWARE\Microsoft\VisualStudio\$VERSION)",
273 "InstallDir", VSInstallPath, nullptr) ||
274 getSystemRegistryString(R"(SOFTWARE\Microsoft\VCExpress\$VERSION)",
275 "InstallDir", VSInstallPath, nullptr)) {
276 if (!VSInstallPath.empty()) {
277 llvm::SmallString<256>
278 VCPath(llvm::StringRef(VSInstallPath.c_str(),
279 VSInstallPath.find(R"(\Common7\IDE)")));
280 llvm::sys::path::append(VCPath, "VC");
281
282 Path = VCPath.str();
283 IsVS2017OrNewer = false;
284 return true;
285 }
286 }
287 return false;
288}
289
290MSVCToolChain::MSVCToolChain(const Driver &D, const llvm::Triple& Triple,
Saleem Abdulrasool819f3912014-10-22 02:37:29 +0000291 const ArgList &Args)
Justin Lebar58891902017-01-05 16:52:29 +0000292 : ToolChain(D, Triple, Args), CudaInstallation(D, Triple, Args) {
Zachary Turner719f58c2014-12-01 23:06:47 +0000293 getProgramPaths().push_back(getDriver().getInstalledDir());
294 if (getDriver().getInstalledDir() != getDriver().Dir)
295 getProgramPaths().push_back(getDriver().Dir);
Reid Kleckner723fabf2017-02-02 19:29:46 +0000296
297 // Check the environment first, since that's probably the user telling us
298 // what they want to use.
299 // Failing that, just try to find the newest Visual Studio version we can
300 // and use its default VC toolchain.
301 findVCToolChainViaEnvironment(VCToolChainPath, IsVS2017OrNewer)
302 || findVCToolChainViaSetupConfig(VCToolChainPath, IsVS2017OrNewer)
303 || findVCToolChainViaRegistry(VCToolChainPath, IsVS2017OrNewer);
Hans Wennborg1cc6cce2013-08-30 09:42:06 +0000304}
305
Saleem Abdulrasool819f3912014-10-22 02:37:29 +0000306Tool *MSVCToolChain::buildLinker() const {
Reid Kleckner723fabf2017-02-02 19:29:46 +0000307 if (VCToolChainPath.empty()) {
308 getDriver().Diag(clang::diag::err_drv_msvc_not_found);
309 return nullptr;
310 }
Douglas Katzman95354292015-06-23 20:42:09 +0000311 return new tools::visualstudio::Linker(*this);
Hans Wennborg1cc6cce2013-08-30 09:42:06 +0000312}
313
Saleem Abdulrasool819f3912014-10-22 02:37:29 +0000314Tool *MSVCToolChain::buildAssembler() const {
Saleem Abdulrasool377066a2014-03-27 22:50:18 +0000315 if (getTriple().isOSBinFormatMachO())
Douglas Katzman95354292015-06-23 20:42:09 +0000316 return new tools::darwin::Assembler(*this);
Alp Tokerc8d4f0f2013-11-22 08:27:46 +0000317 getDriver().Diag(clang::diag::err_no_external_assembler);
Craig Topper92fc2df2014-05-17 16:56:41 +0000318 return nullptr;
Hans Wennborg1cc6cce2013-08-30 09:42:06 +0000319}
320
Saleem Abdulrasool819f3912014-10-22 02:37:29 +0000321bool MSVCToolChain::IsIntegratedAssemblerDefault() const {
Hans Wennborg1cc6cce2013-08-30 09:42:06 +0000322 return true;
323}
324
Saleem Abdulrasool819f3912014-10-22 02:37:29 +0000325bool MSVCToolChain::IsUnwindTablesDefault() const {
Reid Kleckner6b3a9402014-09-04 18:13:12 +0000326 // Emit unwind tables by default on Win64. All non-x86_32 Windows platforms
327 // such as ARM and PPC actually require unwind tables, but LLVM doesn't know
328 // how to generate them yet.
Akira Hatanakae4218132016-05-05 01:41:07 +0000329
330 // Don't emit unwind tables by default for MachO targets.
331 if (getTriple().isOSBinFormatMachO())
332 return false;
333
Reid Kleckner6b3a9402014-09-04 18:13:12 +0000334 return getArch() == llvm::Triple::x86_64;
Hans Wennborg1cc6cce2013-08-30 09:42:06 +0000335}
336
Reid Kleckner8c190832016-12-28 17:41:36 +0000337bool MSVCToolChain::isPICDefault() const {
338 return getArch() == llvm::Triple::x86_64;
339}
340
341bool MSVCToolChain::isPIEDefault() const {
342 return false;
343}
344
345bool MSVCToolChain::isPICDefaultForced() const {
346 return getArch() == llvm::Triple::x86_64;
347}
348
Justin Lebar58891902017-01-05 16:52:29 +0000349void MSVCToolChain::AddCudaIncludeArgs(const ArgList &DriverArgs,
350 ArgStringList &CC1Args) const {
351 CudaInstallation.AddCudaIncludeArgs(DriverArgs, CC1Args);
352}
353
354void MSVCToolChain::printVerboseInfo(raw_ostream &OS) const {
355 CudaInstallation.print(OS);
356}
357
Reid Kleckner723fabf2017-02-02 19:29:46 +0000358// Windows SDKs and VC Toolchains group their contents into subdirectories based
359// on the target architecture. This function converts an llvm::Triple::ArchType
360// to the corresponding subdirectory name.
361static const char *llvmArchToWindowsSDKArch(llvm::Triple::ArchType Arch) {
362 using ArchType = llvm::Triple::ArchType;
363 switch (Arch) {
364 case ArchType::x86:
365 return "x86";
366 case ArchType::x86_64:
367 return "x64";
368 case ArchType::arm:
369 return "arm";
370 default:
371 return "";
372 }
373}
374
375// Similar to the above function, but for Visual Studios before VS2017.
376static const char *llvmArchToLegacyVCArch(llvm::Triple::ArchType Arch) {
377 using ArchType = llvm::Triple::ArchType;
378 switch (Arch) {
379 case ArchType::x86:
380 // x86 is default in legacy VC toolchains.
381 // e.g. x86 libs are directly in /lib as opposed to /lib/x86.
382 return "";
383 case ArchType::x86_64:
384 return "amd64";
385 case ArchType::arm:
386 return "arm";
387 default:
388 return "";
389 }
390}
391
392// Get the path to a specific subdirectory in the current toolchain for
393// a given target architecture.
394// VS2017 changed the VC toolchain layout, so this should be used instead
395// of hardcoding paths.
396std::string
397 MSVCToolChain::getSubDirectoryPath(SubDirectoryType Type,
398 llvm::Triple::ArchType TargetArch) const {
399 llvm::SmallString<256> Path(VCToolChainPath);
400 switch (Type) {
401 case SubDirectoryType::Bin:
402 if (IsVS2017OrNewer) {
403 bool HostIsX64 = llvm::Triple(llvm::sys::getProcessTriple()).isArch64Bit();
404 llvm::sys::path::append(Path,
405 "bin",
406 (HostIsX64 ? "HostX64" : "HostX86"),
407 llvmArchToWindowsSDKArch(TargetArch));
408 }
409 else {
410 llvm::sys::path::append(Path,
411 "bin",
412 llvmArchToLegacyVCArch(TargetArch));
413 }
414 break;
415 case SubDirectoryType::Include:
416 llvm::sys::path::append(Path, "include");
417 break;
418 case SubDirectoryType::Lib:
419 llvm::sys::path::append(Path,
420 "lib",
421 IsVS2017OrNewer
422 ? llvmArchToWindowsSDKArch(TargetArch)
423 : llvmArchToLegacyVCArch(TargetArch));
424 break;
425 }
426 return Path.str();
427}
428
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000429#ifdef USE_WIN32
430static bool readFullStringValue(HKEY hkey, const char *valueName,
431 std::string &value) {
Aaron Ballmanb06a3592016-06-23 14:33:53 +0000432 std::wstring WideValueName;
433 if (!llvm::ConvertUTF8toWide(valueName, WideValueName))
434 return false;
435
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000436 DWORD result = 0;
437 DWORD valueSize = 0;
438 DWORD type = 0;
439 // First just query for the required size.
Aaron Ballmanb06a3592016-06-23 14:33:53 +0000440 result = RegQueryValueExW(hkey, WideValueName.c_str(), NULL, &type, NULL,
441 &valueSize);
442 if (result != ERROR_SUCCESS || type != REG_SZ || !valueSize)
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000443 return false;
444 std::vector<BYTE> buffer(valueSize);
Aaron Ballmanb06a3592016-06-23 14:33:53 +0000445 result = RegQueryValueExW(hkey, WideValueName.c_str(), NULL, NULL, &buffer[0],
446 &valueSize);
447 if (result == ERROR_SUCCESS) {
448 std::wstring WideValue(reinterpret_cast<const wchar_t *>(buffer.data()),
449 valueSize / sizeof(wchar_t));
Zachary Turnere78a3472016-07-28 17:13:32 +0000450 if (valueSize && WideValue.back() == L'\0') {
Etienne Bergeron982a3bc2016-08-30 18:38:25 +0000451 WideValue.pop_back();
Zachary Turnere78a3472016-07-28 17:13:32 +0000452 }
Aaron Ballmanb06a3592016-06-23 14:33:53 +0000453 // The destination buffer must be empty as an invariant of the conversion
454 // function; but this function is sometimes called in a loop that passes in
455 // the same buffer, however. Simply clear it out so we can overwrite it.
456 value.clear();
457 return llvm::convertWideToUTF8(WideValue, value);
458 }
459 return false;
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000460}
461#endif
462
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000463/// \brief Read registry string.
464/// This also supports a means to look for high-versioned keys by use
465/// of a $VERSION placeholder in the key path.
466/// $VERSION in the key path is a placeholder for the version number,
467/// causing the highest value path to be searched for and used.
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000468/// I.e. "SOFTWARE\\Microsoft\\VisualStudio\\$VERSION".
469/// There can be additional characters in the component. Only the numeric
470/// characters are compared. This function only searches HKLM.
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000471static bool getSystemRegistryString(const char *keyPath, const char *valueName,
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000472 std::string &value, std::string *phValue) {
Alp Tokerfcce1832014-06-22 03:27:45 +0000473#ifndef USE_WIN32
474 return false;
475#else
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000476 HKEY hRootKey = HKEY_LOCAL_MACHINE;
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000477 HKEY hKey = NULL;
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000478 long lResult;
479 bool returnValue = false;
480
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000481 const char *placeHolder = strstr(keyPath, "$VERSION");
482 std::string bestName;
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000483 // If we have a $VERSION placeholder, do the highest-version search.
484 if (placeHolder) {
485 const char *keyEnd = placeHolder - 1;
486 const char *nextKey = placeHolder;
487 // Find end of previous key.
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000488 while ((keyEnd > keyPath) && (*keyEnd != '\\'))
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000489 keyEnd--;
490 // Find end of key containing $VERSION.
491 while (*nextKey && (*nextKey != '\\'))
492 nextKey++;
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000493 size_t partialKeyLength = keyEnd - keyPath;
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000494 char partialKey[256];
Daniel Marjamakie1146692016-01-27 07:33:50 +0000495 if (partialKeyLength >= sizeof(partialKey))
496 partialKeyLength = sizeof(partialKey) - 1;
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000497 strncpy(partialKey, keyPath, partialKeyLength);
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000498 partialKey[partialKeyLength] = '\0';
499 HKEY hTopKey = NULL;
Aaron Ballmanb06a3592016-06-23 14:33:53 +0000500 lResult = RegOpenKeyExA(hRootKey, partialKey, 0, KEY_READ | KEY_WOW64_32KEY,
501 &hTopKey);
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000502 if (lResult == ERROR_SUCCESS) {
503 char keyName[256];
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000504 double bestValue = 0.0;
505 DWORD index, size = sizeof(keyName) - 1;
Aaron Ballmanb06a3592016-06-23 14:33:53 +0000506 for (index = 0; RegEnumKeyExA(hTopKey, index, keyName, &size, NULL, NULL,
507 NULL, NULL) == ERROR_SUCCESS;
508 index++) {
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000509 const char *sp = keyName;
Jordan Rosea7d03842013-02-08 22:30:41 +0000510 while (*sp && !isDigit(*sp))
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000511 sp++;
512 if (!*sp)
513 continue;
514 const char *ep = sp + 1;
Jordan Rosea7d03842013-02-08 22:30:41 +0000515 while (*ep && (isDigit(*ep) || (*ep == '.')))
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000516 ep++;
517 char numBuf[32];
518 strncpy(numBuf, sp, sizeof(numBuf) - 1);
519 numBuf[sizeof(numBuf) - 1] = '\0';
Hans Wennborgd2192312013-10-10 18:03:08 +0000520 double dvalue = strtod(numBuf, NULL);
521 if (dvalue > bestValue) {
522 // Test that InstallDir is indeed there before keeping this index.
523 // Open the chosen key path remainder.
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000524 bestName = keyName;
Hans Wennborgd2192312013-10-10 18:03:08 +0000525 // Append rest of key.
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000526 bestName.append(nextKey);
Aaron Ballmanb06a3592016-06-23 14:33:53 +0000527 lResult = RegOpenKeyExA(hTopKey, bestName.c_str(), 0,
528 KEY_READ | KEY_WOW64_32KEY, &hKey);
Hans Wennborgd2192312013-10-10 18:03:08 +0000529 if (lResult == ERROR_SUCCESS) {
Zachary Turnere78a3472016-07-28 17:13:32 +0000530 if (readFullStringValue(hKey, valueName, value)) {
Hans Wennborgd2192312013-10-10 18:03:08 +0000531 bestValue = dvalue;
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000532 if (phValue)
533 *phValue = bestName;
Hans Wennborgd2192312013-10-10 18:03:08 +0000534 returnValue = true;
535 }
536 RegCloseKey(hKey);
537 }
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000538 }
539 size = sizeof(keyName) - 1;
540 }
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000541 RegCloseKey(hTopKey);
542 }
543 } else {
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000544 lResult =
Aaron Ballmanb06a3592016-06-23 14:33:53 +0000545 RegOpenKeyExA(hRootKey, keyPath, 0, KEY_READ | KEY_WOW64_32KEY, &hKey);
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000546 if (lResult == ERROR_SUCCESS) {
Zachary Turnere78a3472016-07-28 17:13:32 +0000547 if (readFullStringValue(hKey, valueName, value))
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000548 returnValue = true;
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000549 if (phValue)
550 phValue->clear();
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000551 RegCloseKey(hKey);
552 }
553 }
554 return returnValue;
Alp Tokerfcce1832014-06-22 03:27:45 +0000555#endif // USE_WIN32
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000556}
557
Igor Kudrinf2e75242015-09-24 05:16:36 +0000558// Find the most recent version of Universal CRT or Windows 10 SDK.
559// vcvarsqueryregistry.bat from Visual Studio 2015 sorts entries in the include
560// directory by name and uses the last one of the list.
561// So we compare entry names lexicographically to find the greatest one.
Reid Kleckner723fabf2017-02-02 19:29:46 +0000562static bool getWindows10SDKVersionFromPath(const std::string &SDKPath,
563 std::string &SDKVersion) {
Igor Kudrinf2e75242015-09-24 05:16:36 +0000564 SDKVersion.clear();
565
566 std::error_code EC;
567 llvm::SmallString<128> IncludePath(SDKPath);
568 llvm::sys::path::append(IncludePath, "Include");
569 for (llvm::sys::fs::directory_iterator DirIt(IncludePath, EC), DirEnd;
570 DirIt != DirEnd && !EC; DirIt.increment(EC)) {
571 if (!llvm::sys::fs::is_directory(DirIt->path()))
572 continue;
573 StringRef CandidateName = llvm::sys::path::filename(DirIt->path());
574 // If WDK is installed, there could be subfolders like "wdf" in the
575 // "Include" directory.
576 // Allow only directories which names start with "10.".
577 if (!CandidateName.startswith("10."))
578 continue;
579 if (CandidateName > SDKVersion)
580 SDKVersion = CandidateName;
581 }
582
583 return !SDKVersion.empty();
584}
585
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000586/// \brief Get Windows SDK installation directory.
Reid Kleckner723fabf2017-02-02 19:29:46 +0000587static bool getWindowsSDKDir(std::string &Path, int &Major,
588 std::string &WindowsSDKIncludeVersion,
589 std::string &WindowsSDKLibVersion) {
Igor Kudrinf2e75242015-09-24 05:16:36 +0000590 std::string RegistrySDKVersion;
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000591 // Try the Windows registry.
Igor Kudrinf2e75242015-09-24 05:16:36 +0000592 if (!getSystemRegistryString(
593 "SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\$VERSION",
594 "InstallationFolder", Path, &RegistrySDKVersion))
595 return false;
596 if (Path.empty() || RegistrySDKVersion.empty())
597 return false;
598
599 WindowsSDKIncludeVersion.clear();
600 WindowsSDKLibVersion.clear();
601 Major = 0;
602 std::sscanf(RegistrySDKVersion.c_str(), "v%d.", &Major);
603 if (Major <= 7)
604 return true;
605 if (Major == 8) {
606 // Windows SDK 8.x installs libraries in a folder whose names depend on the
607 // version of the OS you're targeting. By default choose the newest, which
608 // usually corresponds to the version of the OS you've installed the SDK on.
609 const char *Tests[] = {"winv6.3", "win8", "win7"};
610 for (const char *Test : Tests) {
611 llvm::SmallString<128> TestPath(Path);
612 llvm::sys::path::append(TestPath, "Lib", Test);
613 if (llvm::sys::fs::exists(TestPath.c_str())) {
614 WindowsSDKLibVersion = Test;
615 break;
616 }
617 }
618 return !WindowsSDKLibVersion.empty();
619 }
620 if (Major == 10) {
Reid Kleckner723fabf2017-02-02 19:29:46 +0000621 if (!getWindows10SDKVersionFromPath(Path, WindowsSDKIncludeVersion))
Igor Kudrinf2e75242015-09-24 05:16:36 +0000622 return false;
623 WindowsSDKLibVersion = WindowsSDKIncludeVersion;
624 return true;
625 }
626 // Unsupported SDK version
627 return false;
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000628}
629
Zachary Turner10d75b22014-10-22 20:40:43 +0000630// Gets the library path required to link against the Windows SDK.
631bool MSVCToolChain::getWindowsSDKLibraryPath(std::string &path) const {
632 std::string sdkPath;
633 int sdkMajor = 0;
Igor Kudrinf2e75242015-09-24 05:16:36 +0000634 std::string windowsSDKIncludeVersion;
635 std::string windowsSDKLibVersion;
Zachary Turner10d75b22014-10-22 20:40:43 +0000636
637 path.clear();
Igor Kudrinf2e75242015-09-24 05:16:36 +0000638 if (!getWindowsSDKDir(sdkPath, sdkMajor, windowsSDKIncludeVersion,
639 windowsSDKLibVersion))
Zachary Turner10d75b22014-10-22 20:40:43 +0000640 return false;
641
642 llvm::SmallString<128> libPath(sdkPath);
643 llvm::sys::path::append(libPath, "Lib");
Reid Kleckner723fabf2017-02-02 19:29:46 +0000644 if (sdkMajor >= 8) {
645 llvm::sys::path::append(libPath,
646 windowsSDKLibVersion,
647 "um",
648 llvmArchToWindowsSDKArch(getArch()));
649 } else {
Zachary Turner10d75b22014-10-22 20:40:43 +0000650 switch (getArch()) {
Reid Kleckner723fabf2017-02-02 19:29:46 +0000651 // In Windows SDK 7.x, x86 libraries are directly in the Lib folder.
Zachary Turner10d75b22014-10-22 20:40:43 +0000652 case llvm::Triple::x86:
653 break;
654 case llvm::Triple::x86_64:
655 llvm::sys::path::append(libPath, "x64");
656 break;
657 case llvm::Triple::arm:
658 // It is not necessary to link against Windows SDK 7.x when targeting ARM.
659 return false;
660 default:
661 return false;
662 }
Zachary Turner10d75b22014-10-22 20:40:43 +0000663 }
664
665 path = libPath.str();
666 return true;
667}
668
Reid Kleckner7531f7d2015-09-11 00:09:39 +0000669// Check if the Include path of a specified version of Visual Studio contains
670// specific header files. If not, they are probably shipped with Universal CRT.
Reid Kleckner723fabf2017-02-02 19:29:46 +0000671bool MSVCToolChain::useUniversalCRT() const {
672 llvm::SmallString<128> TestPath(getSubDirectoryPath(SubDirectoryType::Include));
673 llvm::sys::path::append(TestPath, "stdlib.h");
Reid Kleckner7531f7d2015-09-11 00:09:39 +0000674 return !llvm::sys::fs::exists(TestPath);
675}
676
Reid Kleckner723fabf2017-02-02 19:29:46 +0000677static bool getUniversalCRTSdkDir(std::string &Path,
678 std::string &UCRTVersion) {
Reid Kleckner7531f7d2015-09-11 00:09:39 +0000679 // vcvarsqueryregistry.bat for Visual Studio 2015 queries the registry
680 // for the specific key "KitsRoot10". So do we.
681 if (!getSystemRegistryString(
Reid Kleckner723fabf2017-02-02 19:29:46 +0000682 "SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots",
683 "KitsRoot10", Path, nullptr))
Reid Kleckner7531f7d2015-09-11 00:09:39 +0000684 return false;
685
Reid Kleckner723fabf2017-02-02 19:29:46 +0000686 return getWindows10SDKVersionFromPath(Path, UCRTVersion);
Reid Kleckner7531f7d2015-09-11 00:09:39 +0000687}
688
689bool MSVCToolChain::getUniversalCRTLibraryPath(std::string &Path) const {
690 std::string UniversalCRTSdkPath;
691 std::string UCRTVersion;
692
693 Path.clear();
694 if (!getUniversalCRTSdkDir(UniversalCRTSdkPath, UCRTVersion))
695 return false;
696
Reid Kleckner723fabf2017-02-02 19:29:46 +0000697 StringRef ArchName = llvmArchToWindowsSDKArch(getArch());
Reid Kleckner7531f7d2015-09-11 00:09:39 +0000698 if (ArchName.empty())
699 return false;
700
701 llvm::SmallString<128> LibPath(UniversalCRTSdkPath);
702 llvm::sys::path::append(LibPath, "Lib", UCRTVersion, "ucrt", ArchName);
703
704 Path = LibPath.str();
705 return true;
706}
707
Reid Kleckner723fabf2017-02-02 19:29:46 +0000708static VersionTuple getMSVCVersionFromTriple(const llvm::Triple &Triple) {
David L. Jones24fb20c2016-12-07 23:41:58 +0000709 unsigned Major, Minor, Micro;
Reid Kleckner723fabf2017-02-02 19:29:46 +0000710 Triple.getEnvironmentVersion(Major, Minor, Micro);
David L. Jones24fb20c2016-12-07 23:41:58 +0000711 if (Major || Minor || Micro)
712 return VersionTuple(Major, Minor, Micro);
713 return VersionTuple();
714}
715
Reid Kleckner723fabf2017-02-02 19:29:46 +0000716static VersionTuple getMSVCVersionFromExe(const std::string &BinDir) {
Adrian McCarthye4b26fc2016-05-13 23:20:11 +0000717 VersionTuple Version;
718#ifdef USE_WIN32
Reid Kleckner723fabf2017-02-02 19:29:46 +0000719 SmallString<128> ClExe(BinDir);
Adrian McCarthye4b26fc2016-05-13 23:20:11 +0000720 llvm::sys::path::append(ClExe, "cl.exe");
721
722 std::wstring ClExeWide;
723 if (!llvm::ConvertUTF8toWide(ClExe.c_str(), ClExeWide))
724 return Version;
725
726 const DWORD VersionSize = ::GetFileVersionInfoSizeW(ClExeWide.c_str(),
727 nullptr);
728 if (VersionSize == 0)
729 return Version;
730
731 SmallVector<uint8_t, 4 * 1024> VersionBlock(VersionSize);
732 if (!::GetFileVersionInfoW(ClExeWide.c_str(), 0, VersionSize,
733 VersionBlock.data()))
734 return Version;
735
736 VS_FIXEDFILEINFO *FileInfo = nullptr;
737 UINT FileInfoSize = 0;
738 if (!::VerQueryValueW(VersionBlock.data(), L"\\",
739 reinterpret_cast<LPVOID *>(&FileInfo), &FileInfoSize) ||
740 FileInfoSize < sizeof(*FileInfo))
741 return Version;
742
743 const unsigned Major = (FileInfo->dwFileVersionMS >> 16) & 0xFFFF;
744 const unsigned Minor = (FileInfo->dwFileVersionMS ) & 0xFFFF;
745 const unsigned Micro = (FileInfo->dwFileVersionLS >> 16) & 0xFFFF;
746
747 Version = VersionTuple(Major, Minor, Micro);
748#endif
749 return Version;
750}
751
Igor Kudrinf2e75242015-09-24 05:16:36 +0000752void MSVCToolChain::AddSystemIncludeWithSubfolder(
753 const ArgList &DriverArgs, ArgStringList &CC1Args,
754 const std::string &folder, const Twine &subfolder1, const Twine &subfolder2,
755 const Twine &subfolder3) const {
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000756 llvm::SmallString<128> path(folder);
Igor Kudrinf2e75242015-09-24 05:16:36 +0000757 llvm::sys::path::append(path, subfolder1, subfolder2, subfolder3);
Yaron Keren92e1b622015-03-18 10:17:07 +0000758 addSystemInclude(DriverArgs, CC1Args, path);
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000759}
760
Saleem Abdulrasool819f3912014-10-22 02:37:29 +0000761void MSVCToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
762 ArgStringList &CC1Args) const {
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000763 if (DriverArgs.hasArg(options::OPT_nostdinc))
764 return;
765
766 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
Igor Kudrinf2e75242015-09-24 05:16:36 +0000767 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, getDriver().ResourceDir,
768 "include");
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000769 }
770
Nico Weberfd3e1ad2016-04-12 19:04:37 +0000771 // Add %INCLUDE%-like directories from the -imsvc flag.
772 for (const auto &Path : DriverArgs.getAllArgValues(options::OPT__SLASH_imsvc))
773 addSystemInclude(DriverArgs, CC1Args, Path);
774
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000775 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
776 return;
777
Joao Matos792d7af2012-09-04 17:29:52 +0000778 // Honor %INCLUDE%. It should know essential search paths with vcvarsall.bat.
David Majnemer85c25b42016-07-24 17:44:03 +0000779 if (llvm::Optional<std::string> cl_include_dir =
780 llvm::sys::Process::GetEnv("INCLUDE")) {
Joao Matos792d7af2012-09-04 17:29:52 +0000781 SmallVector<StringRef, 8> Dirs;
David Majnemer85c25b42016-07-24 17:44:03 +0000782 StringRef(*cl_include_dir)
Reid Kleckner77b45ba2014-04-23 00:15:01 +0000783 .split(Dirs, ";", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
784 for (StringRef Dir : Dirs)
785 addSystemInclude(DriverArgs, CC1Args, Dir);
786 if (!Dirs.empty())
787 return;
Joao Matos792d7af2012-09-04 17:29:52 +0000788 }
789
Joao Matos792d7af2012-09-04 17:29:52 +0000790 // When built with access to the proper Windows APIs, try to actually find
791 // the correct include paths first.
Reid Kleckner723fabf2017-02-02 19:29:46 +0000792 if (!VCToolChainPath.empty()) {
793 addSystemInclude(DriverArgs,
794 CC1Args,
795 getSubDirectoryPath(SubDirectoryType::Include));
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000796
Reid Kleckner723fabf2017-02-02 19:29:46 +0000797 if (useUniversalCRT()) {
Reid Kleckner7531f7d2015-09-11 00:09:39 +0000798 std::string UniversalCRTSdkPath;
799 std::string UCRTVersion;
800 if (getUniversalCRTSdkDir(UniversalCRTSdkPath, UCRTVersion)) {
Igor Kudrinf2e75242015-09-24 05:16:36 +0000801 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, UniversalCRTSdkPath,
802 "Include", UCRTVersion, "ucrt");
Reid Kleckner7531f7d2015-09-11 00:09:39 +0000803 }
804 }
805
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000806 std::string WindowsSDKDir;
Igor Kudrinf2e75242015-09-24 05:16:36 +0000807 int major;
808 std::string windowsSDKIncludeVersion;
809 std::string windowsSDKLibVersion;
810 if (getWindowsSDKDir(WindowsSDKDir, major, windowsSDKIncludeVersion,
811 windowsSDKLibVersion)) {
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000812 if (major >= 8) {
Igor Kudrinf2e75242015-09-24 05:16:36 +0000813 // Note: windowsSDKIncludeVersion is empty for SDKs prior to v10.
814 // Anyway, llvm::sys::path::append is able to manage it.
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000815 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
Igor Kudrinf2e75242015-09-24 05:16:36 +0000816 "include", windowsSDKIncludeVersion,
817 "shared");
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000818 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
Igor Kudrinf2e75242015-09-24 05:16:36 +0000819 "include", windowsSDKIncludeVersion,
820 "um");
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000821 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
Igor Kudrinf2e75242015-09-24 05:16:36 +0000822 "include", windowsSDKIncludeVersion,
823 "winrt");
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000824 } else {
825 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
826 "include");
827 }
Reid Kleckner77b45ba2014-04-23 00:15:01 +0000828 }
Reid Kleckner723fabf2017-02-02 19:29:46 +0000829
Joao Matos792d7af2012-09-04 17:29:52 +0000830 return;
831 }
Joao Matos792d7af2012-09-04 17:29:52 +0000832
David Majnemerd5f7d192016-07-25 04:47:44 +0000833#if defined(LLVM_ON_WIN32)
Joao Matos792d7af2012-09-04 17:29:52 +0000834 // As a fallback, select default install paths.
Alp Tokerfcce1832014-06-22 03:27:45 +0000835 // FIXME: Don't guess drives and paths like this on Windows.
Joao Matos792d7af2012-09-04 17:29:52 +0000836 const StringRef Paths[] = {
837 "C:/Program Files/Microsoft Visual Studio 10.0/VC/include",
838 "C:/Program Files/Microsoft Visual Studio 9.0/VC/include",
839 "C:/Program Files/Microsoft Visual Studio 9.0/VC/PlatformSDK/Include",
840 "C:/Program Files/Microsoft Visual Studio 8/VC/include",
841 "C:/Program Files/Microsoft Visual Studio 8/VC/PlatformSDK/Include"
842 };
843 addSystemIncludes(DriverArgs, CC1Args, Paths);
David Majnemerd5f7d192016-07-25 04:47:44 +0000844#endif
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000845}
846
Saleem Abdulrasool819f3912014-10-22 02:37:29 +0000847void MSVCToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
848 ArgStringList &CC1Args) const {
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000849 // FIXME: There should probably be logic here to find libc++ on Windows.
850}
David Majnemere11d3732015-06-08 00:22:46 +0000851
David L. Jones24fb20c2016-12-07 23:41:58 +0000852VersionTuple MSVCToolChain::computeMSVCVersion(const Driver *D,
853 const ArgList &Args) const {
854 bool IsWindowsMSVC = getTriple().isWindowsMSVCEnvironment();
855 VersionTuple MSVT = ToolChain::computeMSVCVersion(D, Args);
Reid Kleckner723fabf2017-02-02 19:29:46 +0000856 if (MSVT.empty())
857 MSVT = getMSVCVersionFromTriple(getTriple());
858 if (MSVT.empty() && IsWindowsMSVC)
859 MSVT = getMSVCVersionFromExe(getSubDirectoryPath(SubDirectoryType::Bin));
David L. Jones24fb20c2016-12-07 23:41:58 +0000860 if (MSVT.empty() &&
861 Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions,
862 IsWindowsMSVC)) {
863 // -fms-compatibility-version=18.00 is default.
864 // FIXME: Consider bumping this to 19 (MSVC2015) soon.
865 MSVT = VersionTuple(18);
866 }
867 return MSVT;
868}
869
David Majnemere11d3732015-06-08 00:22:46 +0000870std::string
871MSVCToolChain::ComputeEffectiveClangTriple(const ArgList &Args,
872 types::ID InputType) const {
David L. Jones24fb20c2016-12-07 23:41:58 +0000873 // The MSVC version doesn't care about the architecture, even though it
874 // may look at the triple internally.
875 VersionTuple MSVT = computeMSVCVersion(/*D=*/nullptr, Args);
David Majnemere11d3732015-06-08 00:22:46 +0000876 MSVT = VersionTuple(MSVT.getMajor(), MSVT.getMinor().getValueOr(0),
877 MSVT.getSubminor().getValueOr(0));
878
David L. Jones24fb20c2016-12-07 23:41:58 +0000879 // For the rest of the triple, however, a computed architecture name may
880 // be needed.
881 llvm::Triple Triple(ToolChain::ComputeEffectiveClangTriple(Args, InputType));
David Majnemer75fdd6b2015-06-09 06:30:01 +0000882 if (Triple.getEnvironment() == llvm::Triple::MSVC) {
883 StringRef ObjFmt = Triple.getEnvironmentName().split('-').second;
884 if (ObjFmt.empty())
885 Triple.setEnvironmentName((Twine("msvc") + MSVT.getAsString()).str());
886 else
887 Triple.setEnvironmentName(
888 (Twine("msvc") + MSVT.getAsString() + Twine('-') + ObjFmt).str());
889 }
David Majnemere11d3732015-06-08 00:22:46 +0000890 return Triple.getTriple();
891}
Alexey Samsonov7f2a0d22015-06-19 21:36:47 +0000892
893SanitizerMask MSVCToolChain::getSupportedSanitizers() const {
894 SanitizerMask Res = ToolChain::getSupportedSanitizers();
895 Res |= SanitizerKind::Address;
Alexey Samsonov7f2a0d22015-06-19 21:36:47 +0000896 return Res;
897}
David Majnemer015ce0f2015-07-27 07:32:11 +0000898
Hans Wennborg21d73d22016-01-12 23:17:03 +0000899static void TranslateOptArg(Arg *A, llvm::opt::DerivedArgList &DAL,
900 bool SupportsForcingFramePointer,
901 const char *ExpandChar, const OptTable &Opts) {
902 assert(A->getOption().matches(options::OPT__SLASH_O));
903
904 StringRef OptStr = A->getValue();
905 for (size_t I = 0, E = OptStr.size(); I != E; ++I) {
906 const char &OptChar = *(OptStr.data() + I);
907 switch (OptChar) {
908 default:
909 break;
910 case '1':
911 case '2':
912 case 'x':
913 case 'd':
914 if (&OptChar == ExpandChar) {
915 if (OptChar == 'd') {
916 DAL.AddFlagArg(A, Opts.getOption(options::OPT_O0));
917 } else {
918 if (OptChar == '1') {
919 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "s");
920 } else if (OptChar == '2' || OptChar == 'x') {
921 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
922 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "2");
923 }
David Majnemer259d71a2016-01-21 23:01:11 +0000924 if (SupportsForcingFramePointer &&
925 !DAL.hasArgNoClaim(options::OPT_fno_omit_frame_pointer))
Hans Wennborg21d73d22016-01-12 23:17:03 +0000926 DAL.AddFlagArg(A,
927 Opts.getOption(options::OPT_fomit_frame_pointer));
928 if (OptChar == '1' || OptChar == '2')
929 DAL.AddFlagArg(A,
930 Opts.getOption(options::OPT_ffunction_sections));
931 }
932 }
933 break;
934 case 'b':
Hans Wennborg3270bdb2016-05-24 21:23:29 +0000935 if (I + 1 != E && isdigit(OptStr[I + 1])) {
936 switch (OptStr[I + 1]) {
937 case '0':
938 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_inline));
939 break;
940 case '1':
Hans Wennborg44d061a2016-06-22 16:56:16 +0000941 DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_hint_functions));
Hans Wennborg3270bdb2016-05-24 21:23:29 +0000942 break;
943 case '2':
944 DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_functions));
945 break;
946 }
Hans Wennborg21d73d22016-01-12 23:17:03 +0000947 ++I;
Hans Wennborg3270bdb2016-05-24 21:23:29 +0000948 }
Hans Wennborg21d73d22016-01-12 23:17:03 +0000949 break;
950 case 'g':
951 break;
952 case 'i':
953 if (I + 1 != E && OptStr[I + 1] == '-') {
954 ++I;
955 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_builtin));
956 } else {
957 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
958 }
959 break;
960 case 's':
961 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "s");
962 break;
963 case 't':
964 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "2");
965 break;
966 case 'y': {
967 bool OmitFramePointer = true;
968 if (I + 1 != E && OptStr[I + 1] == '-') {
969 OmitFramePointer = false;
970 ++I;
971 }
972 if (SupportsForcingFramePointer) {
973 if (OmitFramePointer)
974 DAL.AddFlagArg(A,
975 Opts.getOption(options::OPT_fomit_frame_pointer));
976 else
977 DAL.AddFlagArg(
978 A, Opts.getOption(options::OPT_fno_omit_frame_pointer));
Nico Weber9c3fca32016-03-23 15:37:41 +0000979 } else {
980 // Don't warn about /Oy- in 64-bit builds (where
981 // SupportsForcingFramePointer is false). The flag having no effect
982 // there is a compiler-internal optimization, and people shouldn't have
983 // to special-case their build files for 64-bit clang-cl.
984 A->claim();
Hans Wennborg21d73d22016-01-12 23:17:03 +0000985 }
986 break;
987 }
988 }
989 }
990}
991
992static void TranslateDArg(Arg *A, llvm::opt::DerivedArgList &DAL,
993 const OptTable &Opts) {
994 assert(A->getOption().matches(options::OPT_D));
995
996 StringRef Val = A->getValue();
997 size_t Hash = Val.find('#');
998 if (Hash == StringRef::npos || Hash > Val.find('=')) {
999 DAL.append(A);
1000 return;
1001 }
1002
1003 std::string NewVal = Val;
1004 NewVal[Hash] = '=';
1005 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_D), NewVal);
1006}
1007
David Majnemer015ce0f2015-07-27 07:32:11 +00001008llvm::opt::DerivedArgList *
1009MSVCToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args,
Samuel Antao31fef982016-10-27 17:39:44 +00001010 StringRef BoundArch, Action::OffloadKind) const {
David Majnemer015ce0f2015-07-27 07:32:11 +00001011 DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
1012 const OptTable &Opts = getDriver().getOpts();
1013
David Majnemer7ab76f22015-08-25 00:46:45 +00001014 // /Oy and /Oy- only has an effect under X86-32.
1015 bool SupportsForcingFramePointer = getArch() == llvm::Triple::x86;
1016
David Majnemer015ce0f2015-07-27 07:32:11 +00001017 // The -O[12xd] flag actually expands to several flags. We must desugar the
1018 // flags so that options embedded can be negated. For example, the '-O2' flag
1019 // enables '-Oy'. Expanding '-O2' into its constituent flags allows us to
1020 // correctly handle '-O2 -Oy-' where the trailing '-Oy-' disables a single
1021 // aspect of '-O2'.
1022 //
1023 // Note that this expansion logic only applies to the *last* of '[12xd]'.
1024
1025 // First step is to search for the character we'd like to expand.
1026 const char *ExpandChar = nullptr;
1027 for (Arg *A : Args) {
1028 if (!A->getOption().matches(options::OPT__SLASH_O))
1029 continue;
1030 StringRef OptStr = A->getValue();
1031 for (size_t I = 0, E = OptStr.size(); I != E; ++I) {
Hans Wennborgdebfed92016-05-25 00:43:45 +00001032 char OptChar = OptStr[I];
1033 char PrevChar = I > 0 ? OptStr[I - 1] : '0';
1034 if (PrevChar == 'b') {
1035 // OptChar does not expand; it's an argument to the previous char.
1036 continue;
1037 }
David Majnemer015ce0f2015-07-27 07:32:11 +00001038 if (OptChar == '1' || OptChar == '2' || OptChar == 'x' || OptChar == 'd')
1039 ExpandChar = OptStr.data() + I;
1040 }
1041 }
1042
David Majnemer015ce0f2015-07-27 07:32:11 +00001043 for (Arg *A : Args) {
Hans Wennborg21d73d22016-01-12 23:17:03 +00001044 if (A->getOption().matches(options::OPT__SLASH_O)) {
1045 // The -O flag actually takes an amalgam of other options. For example,
1046 // '/Ogyb2' is equivalent to '/Og' '/Oy' '/Ob2'.
1047 TranslateOptArg(A, *DAL, SupportsForcingFramePointer, ExpandChar, Opts);
1048 } else if (A->getOption().matches(options::OPT_D)) {
1049 // Translate -Dfoo#bar into -Dfoo=bar.
1050 TranslateDArg(A, *DAL, Opts);
1051 } else {
David Majnemer015ce0f2015-07-27 07:32:11 +00001052 DAL->append(A);
David Majnemer015ce0f2015-07-27 07:32:11 +00001053 }
1054 }
Hans Wennborg21d73d22016-01-12 23:17:03 +00001055
David Majnemer015ce0f2015-07-27 07:32:11 +00001056 return DAL;
1057}