blob: 4f38ec52f53e4a3604c1afabebd2f1b632be6b4f [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"
Alp Tokerf1ffc842014-06-22 04:31:15 +000019#include "llvm/Config/llvm-config.h"
Reid Kleckner898229a2013-06-14 17:17:23 +000020#include "llvm/Option/Arg.h"
21#include "llvm/Option/ArgList.h"
Adrian McCarthye4b26fc2016-05-13 23:20:11 +000022#include "llvm/Support/ConvertUTF.h"
Chandler Carruth1fc603e2011-12-17 23:10:01 +000023#include "llvm/Support/ErrorHandling.h"
Zachary Turner0eaf8fc2014-10-22 20:40:28 +000024#include "llvm/Support/FileSystem.h"
25#include "llvm/Support/Process.h"
Reid Kleckner6b7156b2015-01-23 19:16:25 +000026#include <cstdio>
27
Chandler Carruth1fc603e2011-12-17 23:10:01 +000028// Include the necessary headers to interface with the Windows registry and
29// environment.
Alp Tokerf1ffc842014-06-22 04:31:15 +000030#if defined(LLVM_ON_WIN32)
Alp Tokerfcce1832014-06-22 03:27:45 +000031#define USE_WIN32
32#endif
33
34#ifdef USE_WIN32
Chandler Carruth1fc603e2011-12-17 23:10:01 +000035 #define WIN32_LEAN_AND_MEAN
36 #define NOGDI
Yaron Keren7fc6f1e2014-12-04 21:46:50 +000037 #ifndef NOMINMAX
38 #define NOMINMAX
39 #endif
Logan Chien733e3c62014-06-24 16:18:10 +000040 #include <windows.h>
Adrian McCarthye4b26fc2016-05-13 23:20:11 +000041
42 #pragma comment(lib, "version.lib")
Chandler Carruth1fc603e2011-12-17 23:10:01 +000043#endif
44
45using namespace clang::driver;
46using namespace clang::driver::toolchains;
47using namespace clang;
Reid Kleckner898229a2013-06-14 17:17:23 +000048using namespace llvm::opt;
Chandler Carruth1fc603e2011-12-17 23:10:01 +000049
Saleem Abdulrasool819f3912014-10-22 02:37:29 +000050MSVCToolChain::MSVCToolChain(const Driver &D, const llvm::Triple& Triple,
51 const ArgList &Args)
Hans Wennborg1cc6cce2013-08-30 09:42:06 +000052 : ToolChain(D, Triple, Args) {
Zachary Turner719f58c2014-12-01 23:06:47 +000053 getProgramPaths().push_back(getDriver().getInstalledDir());
54 if (getDriver().getInstalledDir() != getDriver().Dir)
55 getProgramPaths().push_back(getDriver().Dir);
Hans Wennborg1cc6cce2013-08-30 09:42:06 +000056}
57
Saleem Abdulrasool819f3912014-10-22 02:37:29 +000058Tool *MSVCToolChain::buildLinker() const {
Douglas Katzman95354292015-06-23 20:42:09 +000059 return new tools::visualstudio::Linker(*this);
Hans Wennborg1cc6cce2013-08-30 09:42:06 +000060}
61
Saleem Abdulrasool819f3912014-10-22 02:37:29 +000062Tool *MSVCToolChain::buildAssembler() const {
Saleem Abdulrasool377066a2014-03-27 22:50:18 +000063 if (getTriple().isOSBinFormatMachO())
Douglas Katzman95354292015-06-23 20:42:09 +000064 return new tools::darwin::Assembler(*this);
Alp Tokerc8d4f0f2013-11-22 08:27:46 +000065 getDriver().Diag(clang::diag::err_no_external_assembler);
Craig Topper92fc2df2014-05-17 16:56:41 +000066 return nullptr;
Hans Wennborg1cc6cce2013-08-30 09:42:06 +000067}
68
Saleem Abdulrasool819f3912014-10-22 02:37:29 +000069bool MSVCToolChain::IsIntegratedAssemblerDefault() const {
Hans Wennborg1cc6cce2013-08-30 09:42:06 +000070 return true;
71}
72
Saleem Abdulrasool819f3912014-10-22 02:37:29 +000073bool MSVCToolChain::IsUnwindTablesDefault() const {
Reid Kleckner6b3a9402014-09-04 18:13:12 +000074 // Emit unwind tables by default on Win64. All non-x86_32 Windows platforms
75 // such as ARM and PPC actually require unwind tables, but LLVM doesn't know
76 // how to generate them yet.
Akira Hatanakae4218132016-05-05 01:41:07 +000077
78 // Don't emit unwind tables by default for MachO targets.
79 if (getTriple().isOSBinFormatMachO())
80 return false;
81
Reid Kleckner6b3a9402014-09-04 18:13:12 +000082 return getArch() == llvm::Triple::x86_64;
Hans Wennborg1cc6cce2013-08-30 09:42:06 +000083}
84
Saleem Abdulrasool819f3912014-10-22 02:37:29 +000085bool MSVCToolChain::isPICDefault() const {
Hans Wennborg1cc6cce2013-08-30 09:42:06 +000086 return getArch() == llvm::Triple::x86_64;
87}
88
Saleem Abdulrasool819f3912014-10-22 02:37:29 +000089bool MSVCToolChain::isPIEDefault() const {
Hans Wennborg1cc6cce2013-08-30 09:42:06 +000090 return false;
91}
92
Saleem Abdulrasool819f3912014-10-22 02:37:29 +000093bool MSVCToolChain::isPICDefaultForced() const {
Hans Wennborg1cc6cce2013-08-30 09:42:06 +000094 return getArch() == llvm::Triple::x86_64;
95}
96
Zachary Turner0eaf8fc2014-10-22 20:40:28 +000097#ifdef USE_WIN32
98static bool readFullStringValue(HKEY hkey, const char *valueName,
99 std::string &value) {
100 // FIXME: We should be using the W versions of the registry functions, but
101 // doing so requires UTF8 / UTF16 conversions similar to how we handle command
102 // line arguments. The UTF8 conversion functions are not exposed publicly
103 // from LLVM though, so in order to do this we will probably need to create
104 // a registry abstraction in LLVMSupport that is Windows only.
105 DWORD result = 0;
106 DWORD valueSize = 0;
107 DWORD type = 0;
108 // First just query for the required size.
109 result = RegQueryValueEx(hkey, valueName, NULL, &type, NULL, &valueSize);
110 if (result != ERROR_SUCCESS || type != REG_SZ)
111 return false;
112 std::vector<BYTE> buffer(valueSize);
113 result = RegQueryValueEx(hkey, valueName, NULL, NULL, &buffer[0], &valueSize);
114 if (result == ERROR_SUCCESS)
115 value.assign(reinterpret_cast<const char *>(buffer.data()));
116 return result;
117}
118#endif
119
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000120/// \brief Read registry string.
121/// This also supports a means to look for high-versioned keys by use
122/// of a $VERSION placeholder in the key path.
123/// $VERSION in the key path is a placeholder for the version number,
124/// causing the highest value path to be searched for and used.
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000125/// I.e. "SOFTWARE\\Microsoft\\VisualStudio\\$VERSION".
126/// There can be additional characters in the component. Only the numeric
127/// characters are compared. This function only searches HKLM.
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000128static bool getSystemRegistryString(const char *keyPath, const char *valueName,
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000129 std::string &value, std::string *phValue) {
Alp Tokerfcce1832014-06-22 03:27:45 +0000130#ifndef USE_WIN32
131 return false;
132#else
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000133 HKEY hRootKey = HKEY_LOCAL_MACHINE;
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000134 HKEY hKey = NULL;
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000135 long lResult;
136 bool returnValue = false;
137
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000138 const char *placeHolder = strstr(keyPath, "$VERSION");
139 std::string bestName;
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000140 // If we have a $VERSION placeholder, do the highest-version search.
141 if (placeHolder) {
142 const char *keyEnd = placeHolder - 1;
143 const char *nextKey = placeHolder;
144 // Find end of previous key.
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000145 while ((keyEnd > keyPath) && (*keyEnd != '\\'))
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000146 keyEnd--;
147 // Find end of key containing $VERSION.
148 while (*nextKey && (*nextKey != '\\'))
149 nextKey++;
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000150 size_t partialKeyLength = keyEnd - keyPath;
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000151 char partialKey[256];
Daniel Marjamakie1146692016-01-27 07:33:50 +0000152 if (partialKeyLength >= sizeof(partialKey))
153 partialKeyLength = sizeof(partialKey) - 1;
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000154 strncpy(partialKey, keyPath, partialKeyLength);
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000155 partialKey[partialKeyLength] = '\0';
156 HKEY hTopKey = NULL;
Hans Wennborg935d01d2013-10-09 23:41:48 +0000157 lResult = RegOpenKeyEx(hRootKey, partialKey, 0, KEY_READ | KEY_WOW64_32KEY,
158 &hTopKey);
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000159 if (lResult == ERROR_SUCCESS) {
160 char keyName[256];
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000161 double bestValue = 0.0;
162 DWORD index, size = sizeof(keyName) - 1;
163 for (index = 0; RegEnumKeyEx(hTopKey, index, keyName, &size, NULL,
164 NULL, NULL, NULL) == ERROR_SUCCESS; index++) {
165 const char *sp = keyName;
Jordan Rosea7d03842013-02-08 22:30:41 +0000166 while (*sp && !isDigit(*sp))
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000167 sp++;
168 if (!*sp)
169 continue;
170 const char *ep = sp + 1;
Jordan Rosea7d03842013-02-08 22:30:41 +0000171 while (*ep && (isDigit(*ep) || (*ep == '.')))
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000172 ep++;
173 char numBuf[32];
174 strncpy(numBuf, sp, sizeof(numBuf) - 1);
175 numBuf[sizeof(numBuf) - 1] = '\0';
Hans Wennborgd2192312013-10-10 18:03:08 +0000176 double dvalue = strtod(numBuf, NULL);
177 if (dvalue > bestValue) {
178 // Test that InstallDir is indeed there before keeping this index.
179 // Open the chosen key path remainder.
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000180 bestName = keyName;
Hans Wennborgd2192312013-10-10 18:03:08 +0000181 // Append rest of key.
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000182 bestName.append(nextKey);
183 lResult = RegOpenKeyEx(hTopKey, bestName.c_str(), 0,
Hans Wennborgd2192312013-10-10 18:03:08 +0000184 KEY_READ | KEY_WOW64_32KEY, &hKey);
185 if (lResult == ERROR_SUCCESS) {
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000186 lResult = readFullStringValue(hKey, valueName, value);
Hans Wennborgd2192312013-10-10 18:03:08 +0000187 if (lResult == ERROR_SUCCESS) {
Hans Wennborgd2192312013-10-10 18:03:08 +0000188 bestValue = dvalue;
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000189 if (phValue)
190 *phValue = bestName;
Hans Wennborgd2192312013-10-10 18:03:08 +0000191 returnValue = true;
192 }
193 RegCloseKey(hKey);
194 }
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000195 }
196 size = sizeof(keyName) - 1;
197 }
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000198 RegCloseKey(hTopKey);
199 }
200 } else {
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000201 lResult =
202 RegOpenKeyEx(hRootKey, keyPath, 0, KEY_READ | KEY_WOW64_32KEY, &hKey);
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000203 if (lResult == ERROR_SUCCESS) {
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000204 lResult = readFullStringValue(hKey, valueName, value);
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000205 if (lResult == ERROR_SUCCESS)
206 returnValue = true;
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000207 if (phValue)
208 phValue->clear();
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000209 RegCloseKey(hKey);
210 }
211 }
212 return returnValue;
Alp Tokerfcce1832014-06-22 03:27:45 +0000213#endif // USE_WIN32
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000214}
215
Reid Kleckner7531f7d2015-09-11 00:09:39 +0000216// Convert LLVM's ArchType
217// to the corresponding name of Windows SDK libraries subfolder
218static StringRef getWindowsSDKArch(llvm::Triple::ArchType Arch) {
219 switch (Arch) {
220 case llvm::Triple::x86:
221 return "x86";
222 case llvm::Triple::x86_64:
223 return "x64";
224 case llvm::Triple::arm:
225 return "arm";
226 default:
227 return "";
228 }
229}
230
Igor Kudrinf2e75242015-09-24 05:16:36 +0000231// Find the most recent version of Universal CRT or Windows 10 SDK.
232// vcvarsqueryregistry.bat from Visual Studio 2015 sorts entries in the include
233// directory by name and uses the last one of the list.
234// So we compare entry names lexicographically to find the greatest one.
235static bool getWindows10SDKVersion(const std::string &SDKPath,
236 std::string &SDKVersion) {
237 SDKVersion.clear();
238
239 std::error_code EC;
240 llvm::SmallString<128> IncludePath(SDKPath);
241 llvm::sys::path::append(IncludePath, "Include");
242 for (llvm::sys::fs::directory_iterator DirIt(IncludePath, EC), DirEnd;
243 DirIt != DirEnd && !EC; DirIt.increment(EC)) {
244 if (!llvm::sys::fs::is_directory(DirIt->path()))
245 continue;
246 StringRef CandidateName = llvm::sys::path::filename(DirIt->path());
247 // If WDK is installed, there could be subfolders like "wdf" in the
248 // "Include" directory.
249 // Allow only directories which names start with "10.".
250 if (!CandidateName.startswith("10."))
251 continue;
252 if (CandidateName > SDKVersion)
253 SDKVersion = CandidateName;
254 }
255
256 return !SDKVersion.empty();
257}
258
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000259/// \brief Get Windows SDK installation directory.
Igor Kudrinf2e75242015-09-24 05:16:36 +0000260bool MSVCToolChain::getWindowsSDKDir(std::string &Path, int &Major,
261 std::string &WindowsSDKIncludeVersion,
262 std::string &WindowsSDKLibVersion) const {
263 std::string RegistrySDKVersion;
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000264 // Try the Windows registry.
Igor Kudrinf2e75242015-09-24 05:16:36 +0000265 if (!getSystemRegistryString(
266 "SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\$VERSION",
267 "InstallationFolder", Path, &RegistrySDKVersion))
268 return false;
269 if (Path.empty() || RegistrySDKVersion.empty())
270 return false;
271
272 WindowsSDKIncludeVersion.clear();
273 WindowsSDKLibVersion.clear();
274 Major = 0;
275 std::sscanf(RegistrySDKVersion.c_str(), "v%d.", &Major);
276 if (Major <= 7)
277 return true;
278 if (Major == 8) {
279 // Windows SDK 8.x installs libraries in a folder whose names depend on the
280 // version of the OS you're targeting. By default choose the newest, which
281 // usually corresponds to the version of the OS you've installed the SDK on.
282 const char *Tests[] = {"winv6.3", "win8", "win7"};
283 for (const char *Test : Tests) {
284 llvm::SmallString<128> TestPath(Path);
285 llvm::sys::path::append(TestPath, "Lib", Test);
286 if (llvm::sys::fs::exists(TestPath.c_str())) {
287 WindowsSDKLibVersion = Test;
288 break;
289 }
290 }
291 return !WindowsSDKLibVersion.empty();
292 }
293 if (Major == 10) {
294 if (!getWindows10SDKVersion(Path, WindowsSDKIncludeVersion))
295 return false;
296 WindowsSDKLibVersion = WindowsSDKIncludeVersion;
297 return true;
298 }
299 // Unsupported SDK version
300 return false;
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000301}
302
Zachary Turner10d75b22014-10-22 20:40:43 +0000303// Gets the library path required to link against the Windows SDK.
304bool MSVCToolChain::getWindowsSDKLibraryPath(std::string &path) const {
305 std::string sdkPath;
306 int sdkMajor = 0;
Igor Kudrinf2e75242015-09-24 05:16:36 +0000307 std::string windowsSDKIncludeVersion;
308 std::string windowsSDKLibVersion;
Zachary Turner10d75b22014-10-22 20:40:43 +0000309
310 path.clear();
Igor Kudrinf2e75242015-09-24 05:16:36 +0000311 if (!getWindowsSDKDir(sdkPath, sdkMajor, windowsSDKIncludeVersion,
312 windowsSDKLibVersion))
Zachary Turner10d75b22014-10-22 20:40:43 +0000313 return false;
314
315 llvm::SmallString<128> libPath(sdkPath);
316 llvm::sys::path::append(libPath, "Lib");
317 if (sdkMajor <= 7) {
318 switch (getArch()) {
319 // In Windows SDK 7.x, x86 libraries are directly in the Lib folder.
320 case llvm::Triple::x86:
321 break;
322 case llvm::Triple::x86_64:
323 llvm::sys::path::append(libPath, "x64");
324 break;
325 case llvm::Triple::arm:
326 // It is not necessary to link against Windows SDK 7.x when targeting ARM.
327 return false;
328 default:
329 return false;
330 }
331 } else {
Reid Kleckner7531f7d2015-09-11 00:09:39 +0000332 const StringRef archName = getWindowsSDKArch(getArch());
333 if (archName.empty())
Zachary Turner10d75b22014-10-22 20:40:43 +0000334 return false;
Igor Kudrinf2e75242015-09-24 05:16:36 +0000335 llvm::sys::path::append(libPath, windowsSDKLibVersion, "um", archName);
Zachary Turner10d75b22014-10-22 20:40:43 +0000336 }
337
338 path = libPath.str();
339 return true;
340}
341
Reid Kleckner7531f7d2015-09-11 00:09:39 +0000342// Check if the Include path of a specified version of Visual Studio contains
343// specific header files. If not, they are probably shipped with Universal CRT.
344bool clang::driver::toolchains::MSVCToolChain::useUniversalCRT(
345 std::string &VisualStudioDir) const {
346 llvm::SmallString<128> TestPath(VisualStudioDir);
347 llvm::sys::path::append(TestPath, "VC\\include\\stdlib.h");
348
349 return !llvm::sys::fs::exists(TestPath);
350}
351
352bool MSVCToolChain::getUniversalCRTSdkDir(std::string &Path,
353 std::string &UCRTVersion) const {
354 // vcvarsqueryregistry.bat for Visual Studio 2015 queries the registry
355 // for the specific key "KitsRoot10". So do we.
356 if (!getSystemRegistryString(
357 "SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots", "KitsRoot10",
358 Path, nullptr))
359 return false;
360
Igor Kudrinf2e75242015-09-24 05:16:36 +0000361 return getWindows10SDKVersion(Path, UCRTVersion);
Reid Kleckner7531f7d2015-09-11 00:09:39 +0000362}
363
364bool MSVCToolChain::getUniversalCRTLibraryPath(std::string &Path) const {
365 std::string UniversalCRTSdkPath;
366 std::string UCRTVersion;
367
368 Path.clear();
369 if (!getUniversalCRTSdkDir(UniversalCRTSdkPath, UCRTVersion))
370 return false;
371
372 StringRef ArchName = getWindowsSDKArch(getArch());
373 if (ArchName.empty())
374 return false;
375
376 llvm::SmallString<128> LibPath(UniversalCRTSdkPath);
377 llvm::sys::path::append(LibPath, "Lib", UCRTVersion, "ucrt", ArchName);
378
379 Path = LibPath.str();
380 return true;
381}
382
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000383// Get the location to use for Visual Studio binaries. The location priority
384// is: %VCINSTALLDIR% > %PATH% > newest copy of Visual Studio installed on
385// system (as reported by the registry).
386bool MSVCToolChain::getVisualStudioBinariesFolder(const char *clangProgramPath,
387 std::string &path) const {
388 path.clear();
389
390 SmallString<128> BinDir;
391
392 // First check the environment variables that vsvars32.bat sets.
393 llvm::Optional<std::string> VcInstallDir =
394 llvm::sys::Process::GetEnv("VCINSTALLDIR");
395 if (VcInstallDir.hasValue()) {
396 BinDir = VcInstallDir.getValue();
397 llvm::sys::path::append(BinDir, "bin");
398 } else {
399 // Next walk the PATH, trying to find a cl.exe in the path. If we find one,
400 // use that. However, make sure it's not clang's cl.exe.
401 llvm::Optional<std::string> OptPath = llvm::sys::Process::GetEnv("PATH");
402 if (OptPath.hasValue()) {
403 const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'};
404 SmallVector<StringRef, 8> PathSegments;
405 llvm::SplitString(OptPath.getValue(), PathSegments, EnvPathSeparatorStr);
406
407 for (StringRef PathSegment : PathSegments) {
408 if (PathSegment.empty())
409 continue;
410
411 SmallString<128> FilePath(PathSegment);
412 llvm::sys::path::append(FilePath, "cl.exe");
413 if (llvm::sys::fs::can_execute(FilePath.c_str()) &&
414 !llvm::sys::fs::equivalent(FilePath.c_str(), clangProgramPath)) {
415 // If we found it on the PATH, use it exactly as is with no
416 // modifications.
417 path = PathSegment;
418 return true;
419 }
420 }
421 }
422
423 std::string installDir;
424 // With no VCINSTALLDIR and nothing on the PATH, if we can't find it in the
425 // registry then we have no choice but to fail.
426 if (!getVisualStudioInstallDir(installDir))
427 return false;
428
429 // Regardless of what binary we're ultimately trying to find, we make sure
430 // that this is a Visual Studio directory by checking for cl.exe. We use
431 // cl.exe instead of other binaries like link.exe because programs such as
432 // GnuWin32 also have a utility called link.exe, so cl.exe is the least
433 // ambiguous.
434 BinDir = installDir;
435 llvm::sys::path::append(BinDir, "VC", "bin");
436 SmallString<128> ClPath(BinDir);
437 llvm::sys::path::append(ClPath, "cl.exe");
438
439 if (!llvm::sys::fs::can_execute(ClPath.c_str()))
440 return false;
Hans Wennborge6b994e2014-10-20 23:26:03 +0000441 }
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000442
443 if (BinDir.empty())
444 return false;
445
446 switch (getArch()) {
447 case llvm::Triple::x86:
448 break;
449 case llvm::Triple::x86_64:
450 llvm::sys::path::append(BinDir, "amd64");
451 break;
452 case llvm::Triple::arm:
453 llvm::sys::path::append(BinDir, "arm");
454 break;
455 default:
456 // Whatever this is, Visual Studio doesn't have a toolchain for it.
457 return false;
458 }
459 path = BinDir.str();
460 return true;
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000461}
462
Adrian McCarthye4b26fc2016-05-13 23:20:11 +0000463VersionTuple MSVCToolChain::getMSVCVersionFromExe() const {
464 VersionTuple Version;
465#ifdef USE_WIN32
466 std::string BinPath;
467 if (!getVisualStudioBinariesFolder("", BinPath))
468 return Version;
469 SmallString<128> ClExe = BinPath;
470 llvm::sys::path::append(ClExe, "cl.exe");
471
472 std::wstring ClExeWide;
473 if (!llvm::ConvertUTF8toWide(ClExe.c_str(), ClExeWide))
474 return Version;
475
476 const DWORD VersionSize = ::GetFileVersionInfoSizeW(ClExeWide.c_str(),
477 nullptr);
478 if (VersionSize == 0)
479 return Version;
480
481 SmallVector<uint8_t, 4 * 1024> VersionBlock(VersionSize);
482 if (!::GetFileVersionInfoW(ClExeWide.c_str(), 0, VersionSize,
483 VersionBlock.data()))
484 return Version;
485
486 VS_FIXEDFILEINFO *FileInfo = nullptr;
487 UINT FileInfoSize = 0;
488 if (!::VerQueryValueW(VersionBlock.data(), L"\\",
489 reinterpret_cast<LPVOID *>(&FileInfo), &FileInfoSize) ||
490 FileInfoSize < sizeof(*FileInfo))
491 return Version;
492
493 const unsigned Major = (FileInfo->dwFileVersionMS >> 16) & 0xFFFF;
494 const unsigned Minor = (FileInfo->dwFileVersionMS ) & 0xFFFF;
495 const unsigned Micro = (FileInfo->dwFileVersionLS >> 16) & 0xFFFF;
496
497 Version = VersionTuple(Major, Minor, Micro);
498#endif
499 return Version;
500}
501
Alp Tokerfcce1832014-06-22 03:27:45 +0000502// Get Visual Studio installation directory.
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000503bool MSVCToolChain::getVisualStudioInstallDir(std::string &path) const {
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000504 // First check the environment variables that vsvars32.bat sets.
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000505 const char *vcinstalldir = getenv("VCINSTALLDIR");
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000506 if (vcinstalldir) {
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000507 path = vcinstalldir;
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000508 path = path.substr(0, path.find("\\VC"));
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000509 return true;
510 }
511
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000512 std::string vsIDEInstallDir;
513 std::string vsExpressIDEInstallDir;
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000514 // Then try the windows registry.
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000515 bool hasVCDir =
516 getSystemRegistryString("SOFTWARE\\Microsoft\\VisualStudio\\$VERSION",
517 "InstallDir", vsIDEInstallDir, nullptr);
518 if (hasVCDir && !vsIDEInstallDir.empty()) {
519 path = vsIDEInstallDir.substr(0, vsIDEInstallDir.find("\\Common7\\IDE"));
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000520 return true;
521 }
522
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000523 bool hasVCExpressDir =
524 getSystemRegistryString("SOFTWARE\\Microsoft\\VCExpress\\$VERSION",
525 "InstallDir", vsExpressIDEInstallDir, nullptr);
526 if (hasVCExpressDir && !vsExpressIDEInstallDir.empty()) {
527 path = vsExpressIDEInstallDir.substr(
528 0, vsIDEInstallDir.find("\\Common7\\IDE"));
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000529 return true;
530 }
531
532 // Try the environment.
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000533 const char *vs120comntools = getenv("VS120COMNTOOLS");
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000534 const char *vs100comntools = getenv("VS100COMNTOOLS");
535 const char *vs90comntools = getenv("VS90COMNTOOLS");
536 const char *vs80comntools = getenv("VS80COMNTOOLS");
Alp Tokerfcce1832014-06-22 03:27:45 +0000537
538 const char *vscomntools = nullptr;
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000539
Alp Tokera2074402014-06-22 03:27:52 +0000540 // Find any version we can
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000541 if (vs120comntools)
542 vscomntools = vs120comntools;
543 else if (vs100comntools)
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000544 vscomntools = vs100comntools;
545 else if (vs90comntools)
546 vscomntools = vs90comntools;
547 else if (vs80comntools)
548 vscomntools = vs80comntools;
549
550 if (vscomntools && *vscomntools) {
551 const char *p = strstr(vscomntools, "\\Common7\\Tools");
552 path = p ? std::string(vscomntools, p) : vscomntools;
553 return true;
554 }
555 return false;
556}
557
Igor Kudrinf2e75242015-09-24 05:16:36 +0000558void MSVCToolChain::AddSystemIncludeWithSubfolder(
559 const ArgList &DriverArgs, ArgStringList &CC1Args,
560 const std::string &folder, const Twine &subfolder1, const Twine &subfolder2,
561 const Twine &subfolder3) const {
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000562 llvm::SmallString<128> path(folder);
Igor Kudrinf2e75242015-09-24 05:16:36 +0000563 llvm::sys::path::append(path, subfolder1, subfolder2, subfolder3);
Yaron Keren92e1b622015-03-18 10:17:07 +0000564 addSystemInclude(DriverArgs, CC1Args, path);
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000565}
566
Saleem Abdulrasool819f3912014-10-22 02:37:29 +0000567void MSVCToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
568 ArgStringList &CC1Args) const {
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000569 if (DriverArgs.hasArg(options::OPT_nostdinc))
570 return;
571
572 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
Igor Kudrinf2e75242015-09-24 05:16:36 +0000573 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, getDriver().ResourceDir,
574 "include");
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000575 }
576
Nico Weberfd3e1ad2016-04-12 19:04:37 +0000577 // Add %INCLUDE%-like directories from the -imsvc flag.
578 for (const auto &Path : DriverArgs.getAllArgValues(options::OPT__SLASH_imsvc))
579 addSystemInclude(DriverArgs, CC1Args, Path);
580
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000581 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
582 return;
583
Joao Matos792d7af2012-09-04 17:29:52 +0000584 // Honor %INCLUDE%. It should know essential search paths with vcvarsall.bat.
585 if (const char *cl_include_dir = getenv("INCLUDE")) {
586 SmallVector<StringRef, 8> Dirs;
Reid Kleckner77b45ba2014-04-23 00:15:01 +0000587 StringRef(cl_include_dir)
588 .split(Dirs, ";", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
589 for (StringRef Dir : Dirs)
590 addSystemInclude(DriverArgs, CC1Args, Dir);
591 if (!Dirs.empty())
592 return;
Joao Matos792d7af2012-09-04 17:29:52 +0000593 }
594
595 std::string VSDir;
Joao Matos792d7af2012-09-04 17:29:52 +0000596
597 // When built with access to the proper Windows APIs, try to actually find
598 // the correct include paths first.
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000599 if (getVisualStudioInstallDir(VSDir)) {
600 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, VSDir, "VC\\include");
601
Reid Kleckner7531f7d2015-09-11 00:09:39 +0000602 if (useUniversalCRT(VSDir)) {
603 std::string UniversalCRTSdkPath;
604 std::string UCRTVersion;
605 if (getUniversalCRTSdkDir(UniversalCRTSdkPath, UCRTVersion)) {
Igor Kudrinf2e75242015-09-24 05:16:36 +0000606 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, UniversalCRTSdkPath,
607 "Include", UCRTVersion, "ucrt");
Reid Kleckner7531f7d2015-09-11 00:09:39 +0000608 }
609 }
610
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000611 std::string WindowsSDKDir;
Igor Kudrinf2e75242015-09-24 05:16:36 +0000612 int major;
613 std::string windowsSDKIncludeVersion;
614 std::string windowsSDKLibVersion;
615 if (getWindowsSDKDir(WindowsSDKDir, major, windowsSDKIncludeVersion,
616 windowsSDKLibVersion)) {
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000617 if (major >= 8) {
Igor Kudrinf2e75242015-09-24 05:16:36 +0000618 // Note: windowsSDKIncludeVersion is empty for SDKs prior to v10.
619 // Anyway, llvm::sys::path::append is able to manage it.
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000620 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
Igor Kudrinf2e75242015-09-24 05:16:36 +0000621 "include", windowsSDKIncludeVersion,
622 "shared");
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000623 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
Igor Kudrinf2e75242015-09-24 05:16:36 +0000624 "include", windowsSDKIncludeVersion,
625 "um");
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000626 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
Igor Kudrinf2e75242015-09-24 05:16:36 +0000627 "include", windowsSDKIncludeVersion,
628 "winrt");
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000629 } else {
630 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
631 "include");
632 }
Reid Kleckner77b45ba2014-04-23 00:15:01 +0000633 } else {
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000634 addSystemInclude(DriverArgs, CC1Args, VSDir);
Reid Kleckner77b45ba2014-04-23 00:15:01 +0000635 }
Joao Matos792d7af2012-09-04 17:29:52 +0000636 return;
637 }
Joao Matos792d7af2012-09-04 17:29:52 +0000638
639 // As a fallback, select default install paths.
Alp Tokerfcce1832014-06-22 03:27:45 +0000640 // FIXME: Don't guess drives and paths like this on Windows.
Joao Matos792d7af2012-09-04 17:29:52 +0000641 const StringRef Paths[] = {
642 "C:/Program Files/Microsoft Visual Studio 10.0/VC/include",
643 "C:/Program Files/Microsoft Visual Studio 9.0/VC/include",
644 "C:/Program Files/Microsoft Visual Studio 9.0/VC/PlatformSDK/Include",
645 "C:/Program Files/Microsoft Visual Studio 8/VC/include",
646 "C:/Program Files/Microsoft Visual Studio 8/VC/PlatformSDK/Include"
647 };
648 addSystemIncludes(DriverArgs, CC1Args, Paths);
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000649}
650
Saleem Abdulrasool819f3912014-10-22 02:37:29 +0000651void MSVCToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
652 ArgStringList &CC1Args) const {
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000653 // FIXME: There should probably be logic here to find libc++ on Windows.
654}
David Majnemere11d3732015-06-08 00:22:46 +0000655
656std::string
657MSVCToolChain::ComputeEffectiveClangTriple(const ArgList &Args,
658 types::ID InputType) const {
659 std::string TripleStr =
660 ToolChain::ComputeEffectiveClangTriple(Args, InputType);
661 llvm::Triple Triple(TripleStr);
662 VersionTuple MSVT =
Adrian McCarthye4b26fc2016-05-13 23:20:11 +0000663 tools::visualstudio::getMSVCVersion(/*D=*/nullptr, *this, Triple, Args,
David Majnemere11d3732015-06-08 00:22:46 +0000664 /*IsWindowsMSVC=*/true);
665 if (MSVT.empty())
666 return TripleStr;
667
668 MSVT = VersionTuple(MSVT.getMajor(), MSVT.getMinor().getValueOr(0),
669 MSVT.getSubminor().getValueOr(0));
670
David Majnemer75fdd6b2015-06-09 06:30:01 +0000671 if (Triple.getEnvironment() == llvm::Triple::MSVC) {
672 StringRef ObjFmt = Triple.getEnvironmentName().split('-').second;
673 if (ObjFmt.empty())
674 Triple.setEnvironmentName((Twine("msvc") + MSVT.getAsString()).str());
675 else
676 Triple.setEnvironmentName(
677 (Twine("msvc") + MSVT.getAsString() + Twine('-') + ObjFmt).str());
678 }
David Majnemere11d3732015-06-08 00:22:46 +0000679 return Triple.getTriple();
680}
Alexey Samsonov7f2a0d22015-06-19 21:36:47 +0000681
682SanitizerMask MSVCToolChain::getSupportedSanitizers() const {
683 SanitizerMask Res = ToolChain::getSupportedSanitizers();
684 Res |= SanitizerKind::Address;
Alexey Samsonov7f2a0d22015-06-19 21:36:47 +0000685 return Res;
686}
David Majnemer015ce0f2015-07-27 07:32:11 +0000687
Hans Wennborg21d73d22016-01-12 23:17:03 +0000688static void TranslateOptArg(Arg *A, llvm::opt::DerivedArgList &DAL,
689 bool SupportsForcingFramePointer,
690 const char *ExpandChar, const OptTable &Opts) {
691 assert(A->getOption().matches(options::OPT__SLASH_O));
692
693 StringRef OptStr = A->getValue();
694 for (size_t I = 0, E = OptStr.size(); I != E; ++I) {
695 const char &OptChar = *(OptStr.data() + I);
696 switch (OptChar) {
697 default:
698 break;
699 case '1':
700 case '2':
701 case 'x':
702 case 'd':
703 if (&OptChar == ExpandChar) {
704 if (OptChar == 'd') {
705 DAL.AddFlagArg(A, Opts.getOption(options::OPT_O0));
706 } else {
707 if (OptChar == '1') {
708 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "s");
709 } else if (OptChar == '2' || OptChar == 'x') {
710 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
711 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "2");
712 }
David Majnemer259d71a2016-01-21 23:01:11 +0000713 if (SupportsForcingFramePointer &&
714 !DAL.hasArgNoClaim(options::OPT_fno_omit_frame_pointer))
Hans Wennborg21d73d22016-01-12 23:17:03 +0000715 DAL.AddFlagArg(A,
716 Opts.getOption(options::OPT_fomit_frame_pointer));
717 if (OptChar == '1' || OptChar == '2')
718 DAL.AddFlagArg(A,
719 Opts.getOption(options::OPT_ffunction_sections));
720 }
721 }
722 break;
723 case 'b':
724 if (I + 1 != E && isdigit(OptStr[I + 1]))
725 ++I;
726 break;
727 case 'g':
728 break;
729 case 'i':
730 if (I + 1 != E && OptStr[I + 1] == '-') {
731 ++I;
732 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_builtin));
733 } else {
734 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
735 }
736 break;
737 case 's':
738 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "s");
739 break;
740 case 't':
741 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "2");
742 break;
743 case 'y': {
744 bool OmitFramePointer = true;
745 if (I + 1 != E && OptStr[I + 1] == '-') {
746 OmitFramePointer = false;
747 ++I;
748 }
749 if (SupportsForcingFramePointer) {
750 if (OmitFramePointer)
751 DAL.AddFlagArg(A,
752 Opts.getOption(options::OPT_fomit_frame_pointer));
753 else
754 DAL.AddFlagArg(
755 A, Opts.getOption(options::OPT_fno_omit_frame_pointer));
Nico Weber9c3fca32016-03-23 15:37:41 +0000756 } else {
757 // Don't warn about /Oy- in 64-bit builds (where
758 // SupportsForcingFramePointer is false). The flag having no effect
759 // there is a compiler-internal optimization, and people shouldn't have
760 // to special-case their build files for 64-bit clang-cl.
761 A->claim();
Hans Wennborg21d73d22016-01-12 23:17:03 +0000762 }
763 break;
764 }
765 }
766 }
767}
768
769static void TranslateDArg(Arg *A, llvm::opt::DerivedArgList &DAL,
770 const OptTable &Opts) {
771 assert(A->getOption().matches(options::OPT_D));
772
773 StringRef Val = A->getValue();
774 size_t Hash = Val.find('#');
775 if (Hash == StringRef::npos || Hash > Val.find('=')) {
776 DAL.append(A);
777 return;
778 }
779
780 std::string NewVal = Val;
781 NewVal[Hash] = '=';
782 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_D), NewVal);
783}
784
David Majnemer015ce0f2015-07-27 07:32:11 +0000785llvm::opt::DerivedArgList *
786MSVCToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args,
787 const char *BoundArch) const {
788 DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
789 const OptTable &Opts = getDriver().getOpts();
790
David Majnemer7ab76f22015-08-25 00:46:45 +0000791 // /Oy and /Oy- only has an effect under X86-32.
792 bool SupportsForcingFramePointer = getArch() == llvm::Triple::x86;
793
David Majnemer015ce0f2015-07-27 07:32:11 +0000794 // The -O[12xd] flag actually expands to several flags. We must desugar the
795 // flags so that options embedded can be negated. For example, the '-O2' flag
796 // enables '-Oy'. Expanding '-O2' into its constituent flags allows us to
797 // correctly handle '-O2 -Oy-' where the trailing '-Oy-' disables a single
798 // aspect of '-O2'.
799 //
800 // Note that this expansion logic only applies to the *last* of '[12xd]'.
801
802 // First step is to search for the character we'd like to expand.
803 const char *ExpandChar = nullptr;
804 for (Arg *A : Args) {
805 if (!A->getOption().matches(options::OPT__SLASH_O))
806 continue;
807 StringRef OptStr = A->getValue();
808 for (size_t I = 0, E = OptStr.size(); I != E; ++I) {
809 const char &OptChar = *(OptStr.data() + I);
810 if (OptChar == '1' || OptChar == '2' || OptChar == 'x' || OptChar == 'd')
811 ExpandChar = OptStr.data() + I;
812 }
813 }
814
David Majnemer015ce0f2015-07-27 07:32:11 +0000815 for (Arg *A : Args) {
Hans Wennborg21d73d22016-01-12 23:17:03 +0000816 if (A->getOption().matches(options::OPT__SLASH_O)) {
817 // The -O flag actually takes an amalgam of other options. For example,
818 // '/Ogyb2' is equivalent to '/Og' '/Oy' '/Ob2'.
819 TranslateOptArg(A, *DAL, SupportsForcingFramePointer, ExpandChar, Opts);
820 } else if (A->getOption().matches(options::OPT_D)) {
821 // Translate -Dfoo#bar into -Dfoo=bar.
822 TranslateDArg(A, *DAL, Opts);
823 } else {
David Majnemer015ce0f2015-07-27 07:32:11 +0000824 DAL->append(A);
David Majnemer015ce0f2015-07-27 07:32:11 +0000825 }
826 }
Hans Wennborg21d73d22016-01-12 23:17:03 +0000827
David Majnemer015ce0f2015-07-27 07:32:11 +0000828 return DAL;
829}