blob: ae41ee9e22cf1d10ad350db7dca2ffc25edc56cc [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
David L. Jonesf561aba2017-03-08 01:02:16 +000010#include "MSVC.h"
11#include "CommonArgs.h"
Zachary Turnerf6302522017-03-15 16:07:35 +000012#include "Darwin.h"
Jordan Rosea7d03842013-02-08 22:30:41 +000013#include "clang/Basic/CharInfo.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000014#include "clang/Basic/Version.h"
Chandler Carruth1fc603e2011-12-17 23:10:01 +000015#include "clang/Driver/Compilation.h"
16#include "clang/Driver/Driver.h"
Rafael Espindola79764462013-03-24 15:06:53 +000017#include "clang/Driver/DriverDiagnostic.h"
Chandler Carruth1fc603e2011-12-17 23:10:01 +000018#include "clang/Driver/Options.h"
David L. Jonesf561aba2017-03-08 01:02:16 +000019#include "clang/Driver/SanitizerArgs.h"
Zachary Turner0eaf8fc2014-10-22 20:40:28 +000020#include "llvm/ADT/StringExtras.h"
David L. Jones24fb20c2016-12-07 23:41:58 +000021#include "llvm/ADT/StringSwitch.h"
Alp Tokerf1ffc842014-06-22 04:31:15 +000022#include "llvm/Config/llvm-config.h"
Reid Kleckner898229a2013-06-14 17:17:23 +000023#include "llvm/Option/Arg.h"
24#include "llvm/Option/ArgList.h"
Adrian McCarthye4b26fc2016-05-13 23:20:11 +000025#include "llvm/Support/ConvertUTF.h"
Chandler Carruth1fc603e2011-12-17 23:10:01 +000026#include "llvm/Support/ErrorHandling.h"
Zachary Turner0eaf8fc2014-10-22 20:40:28 +000027#include "llvm/Support/FileSystem.h"
Zachary Turnerf6302522017-03-15 16:07:35 +000028#include "llvm/Support/Host.h"
29#include "llvm/Support/MemoryBuffer.h"
Mehdi Amini9670f842016-07-18 19:02:11 +000030#include "llvm/Support/Path.h"
Zachary Turner0eaf8fc2014-10-22 20:40:28 +000031#include "llvm/Support/Process.h"
Reid Kleckner6b7156b2015-01-23 19:16:25 +000032#include <cstdio>
33
Reid Kleckner723fabf2017-02-02 19:29:46 +000034// Include the necessary headers to interface with the Windows registry and
35// environment.
Reid Klecknerbf183552017-02-02 19:36:22 +000036#if defined(LLVM_ON_WIN32)
37#define USE_WIN32
38#endif
39
Alp Tokerfcce1832014-06-22 03:27:45 +000040#ifdef USE_WIN32
Chandler Carruth1fc603e2011-12-17 23:10:01 +000041 #define WIN32_LEAN_AND_MEAN
42 #define NOGDI
Yaron Keren7fc6f1e2014-12-04 21:46:50 +000043 #ifndef NOMINMAX
44 #define NOMINMAX
45 #endif
Logan Chien733e3c62014-06-24 16:18:10 +000046 #include <windows.h>
Zachary Turner545202b2017-03-15 17:09:36 +000047#endif
48
49#ifdef _MSC_VER
50// Don't support SetupApi on MinGW.
51#define USE_MSVC_SETUP_API
Zachary Turnerf6302522017-03-15 16:07:35 +000052
53// Make sure this comes before MSVCSetupApi.h
54#include <comdef.h>
55
56#include "MSVCSetupApi.h"
57#include "llvm/Support/COM.h"
58_COM_SMARTPTR_TYPEDEF(ISetupConfiguration, __uuidof(ISetupConfiguration));
59_COM_SMARTPTR_TYPEDEF(ISetupConfiguration2, __uuidof(ISetupConfiguration2));
60_COM_SMARTPTR_TYPEDEF(ISetupHelper, __uuidof(ISetupHelper));
61_COM_SMARTPTR_TYPEDEF(IEnumSetupInstances, __uuidof(IEnumSetupInstances));
62_COM_SMARTPTR_TYPEDEF(ISetupInstance, __uuidof(ISetupInstance));
63_COM_SMARTPTR_TYPEDEF(ISetupInstance2, __uuidof(ISetupInstance2));
Chandler Carruth1fc603e2011-12-17 23:10:01 +000064#endif
65
66using namespace clang::driver;
67using namespace clang::driver::toolchains;
David L. Jonesf561aba2017-03-08 01:02:16 +000068using namespace clang::driver::tools;
Chandler Carruth1fc603e2011-12-17 23:10:01 +000069using namespace clang;
Reid Kleckner898229a2013-06-14 17:17:23 +000070using namespace llvm::opt;
Chandler Carruth1fc603e2011-12-17 23:10:01 +000071
Zachary Turnerf6302522017-03-15 16:07:35 +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,
Stephan T. Lavavej4c30b742017-08-21 22:19:33 +000079 MSVCToolChain::ToolsetLayout &VSLayout) {
Zachary Turnerf6302522017-03-15 16:07:35 +000080 // 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);
Stephan T. Lavavej4c30b742017-08-21 22:19:33 +000087 VSLayout = MSVCToolChain::ToolsetLayout::VS2017OrNewer;
Zachary Turnerf6302522017-03-15 16:07:35 +000088 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);
Stephan T. Lavavej4c30b742017-08-21 22:19:33 +000097 VSLayout = MSVCToolChain::ToolsetLayout::OlderVS;
Zachary Turnerf6302522017-03-15 16:07:35 +000098 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.
Hans Wennborg6dc120a2017-05-17 15:27:44 +0000128 llvm::StringRef TestPath = PathEntry;
129 bool IsBin = llvm::sys::path::filename(TestPath).equals_lower("bin");
130 if (!IsBin) {
131 // Strip any architecture subdir like "amd64".
132 TestPath = llvm::sys::path::parent_path(TestPath);
133 IsBin = llvm::sys::path::filename(TestPath).equals_lower("bin");
134 }
135 if (IsBin) {
136 llvm::StringRef ParentPath = llvm::sys::path::parent_path(TestPath);
Stephan T. Lavavej4c30b742017-08-21 22:19:33 +0000137 llvm::StringRef ParentFilename = llvm::sys::path::filename(ParentPath);
138 if (ParentFilename == "VC") {
Zachary Turnerf6302522017-03-15 16:07:35 +0000139 Path = ParentPath;
Stephan T. Lavavej4c30b742017-08-21 22:19:33 +0000140 VSLayout = MSVCToolChain::ToolsetLayout::OlderVS;
141 return true;
142 }
143 if (ParentFilename == "x86ret" || ParentFilename == "x86chk"
144 || ParentFilename == "amd64ret" || ParentFilename == "amd64chk") {
145 Path = ParentPath;
146 VSLayout = MSVCToolChain::ToolsetLayout::DevDivInternal;
Zachary Turnerf6302522017-03-15 16:07:35 +0000147 return true;
148 }
149
150 } else {
151 // This could be a new (>=VS2017) toolchain. If it is, we should find
152 // path components with these prefixes when walking backwards through
153 // the path.
154 // Note: empty strings match anything.
155 llvm::StringRef ExpectedPrefixes[] = {"", "Host", "bin", "",
156 "MSVC", "Tools", "VC"};
157
158 auto It = llvm::sys::path::rbegin(PathEntry);
159 auto End = llvm::sys::path::rend(PathEntry);
160 for (llvm::StringRef Prefix : ExpectedPrefixes) {
161 if (It == End)
162 goto NotAToolChain;
163 if (!It->startswith(Prefix))
164 goto NotAToolChain;
165 ++It;
166 }
167
168 // We've found a new toolchain!
169 // Back up 3 times (/bin/Host/arch) to get the root path.
170 llvm::StringRef ToolChainPath(PathEntry);
171 for (int i = 0; i < 3; ++i)
172 ToolChainPath = llvm::sys::path::parent_path(ToolChainPath);
173
174 Path = ToolChainPath;
Stephan T. Lavavej4c30b742017-08-21 22:19:33 +0000175 VSLayout = MSVCToolChain::ToolsetLayout::VS2017OrNewer;
Zachary Turnerf6302522017-03-15 16:07:35 +0000176 return true;
177 }
178
179 NotAToolChain:
180 continue;
181 }
182 }
183 return false;
184}
185
186// Query the Setup Config server for installs, then pick the newest version
187// and find its default VC toolchain.
188// This is the preferred way to discover new Visual Studios, as they're no
189// longer listed in the registry.
190static bool findVCToolChainViaSetupConfig(std::string &Path,
Stephan T. Lavavej4c30b742017-08-21 22:19:33 +0000191 MSVCToolChain::ToolsetLayout &VSLayout) {
Zachary Turner545202b2017-03-15 17:09:36 +0000192#if !defined(USE_MSVC_SETUP_API)
Zachary Turnerf6302522017-03-15 16:07:35 +0000193 return false;
194#else
195 // FIXME: This really should be done once in the top-level program's main
196 // function, as it may have already been initialized with a different
197 // threading model otherwise.
198 llvm::sys::InitializeCOMRAII COM(llvm::sys::COMThreadingMode::SingleThreaded);
199 HRESULT HR;
200
201 // _com_ptr_t will throw a _com_error if a COM calls fail.
202 // The LLVM coding standards forbid exception handling, so we'll have to
203 // stop them from being thrown in the first place.
204 // The destructor will put the regular error handler back when we leave
205 // this scope.
206 struct SuppressCOMErrorsRAII {
207 static void __stdcall handler(HRESULT hr, IErrorInfo *perrinfo) {}
208
209 SuppressCOMErrorsRAII() { _set_com_error_handler(handler); }
210
211 ~SuppressCOMErrorsRAII() { _set_com_error_handler(_com_raise_error); }
212
213 } COMErrorSuppressor;
214
215 ISetupConfigurationPtr Query;
216 HR = Query.CreateInstance(__uuidof(SetupConfiguration));
217 if (FAILED(HR))
218 return false;
219
220 IEnumSetupInstancesPtr EnumInstances;
221 HR = ISetupConfiguration2Ptr(Query)->EnumAllInstances(&EnumInstances);
222 if (FAILED(HR))
223 return false;
224
225 ISetupInstancePtr Instance;
226 HR = EnumInstances->Next(1, &Instance, nullptr);
227 if (HR != S_OK)
228 return false;
229
230 ISetupInstancePtr NewestInstance;
231 Optional<uint64_t> NewestVersionNum;
232 do {
233 bstr_t VersionString;
234 uint64_t VersionNum;
235 HR = Instance->GetInstallationVersion(VersionString.GetAddress());
236 if (FAILED(HR))
237 continue;
238 HR = ISetupHelperPtr(Query)->ParseVersion(VersionString, &VersionNum);
239 if (FAILED(HR))
240 continue;
241 if (!NewestVersionNum || (VersionNum > NewestVersionNum)) {
242 NewestInstance = Instance;
243 NewestVersionNum = VersionNum;
244 }
245 } while ((HR = EnumInstances->Next(1, &Instance, nullptr)) == S_OK);
246
247 if (!NewestInstance)
248 return false;
249
250 bstr_t VCPathWide;
251 HR = NewestInstance->ResolvePath(L"VC", VCPathWide.GetAddress());
252 if (FAILED(HR))
253 return false;
254
255 std::string VCRootPath;
256 llvm::convertWideToUTF8(std::wstring(VCPathWide), VCRootPath);
257
258 llvm::SmallString<256> ToolsVersionFilePath(VCRootPath);
259 llvm::sys::path::append(ToolsVersionFilePath, "Auxiliary", "Build",
260 "Microsoft.VCToolsVersion.default.txt");
261
262 auto ToolsVersionFile = llvm::MemoryBuffer::getFile(ToolsVersionFilePath);
263 if (!ToolsVersionFile)
264 return false;
265
266 llvm::SmallString<256> ToolchainPath(VCRootPath);
267 llvm::sys::path::append(ToolchainPath, "Tools", "MSVC",
268 ToolsVersionFile->get()->getBuffer().rtrim());
269 if (!llvm::sys::fs::is_directory(ToolchainPath))
270 return false;
271
272 Path = ToolchainPath.str();
Stephan T. Lavavej4c30b742017-08-21 22:19:33 +0000273 VSLayout = MSVCToolChain::ToolsetLayout::VS2017OrNewer;
Zachary Turnerf6302522017-03-15 16:07:35 +0000274 return true;
275#endif
276}
277
278// Look in the registry for Visual Studio installs, and use that to get
279// a toolchain path. VS2017 and newer don't get added to the registry.
280// So if we find something here, we know that it's an older version.
281static bool findVCToolChainViaRegistry(std::string &Path,
Stephan T. Lavavej4c30b742017-08-21 22:19:33 +0000282 MSVCToolChain::ToolsetLayout &VSLayout) {
Zachary Turnerf6302522017-03-15 16:07:35 +0000283 std::string VSInstallPath;
284 if (getSystemRegistryString(R"(SOFTWARE\Microsoft\VisualStudio\$VERSION)",
285 "InstallDir", VSInstallPath, nullptr) ||
286 getSystemRegistryString(R"(SOFTWARE\Microsoft\VCExpress\$VERSION)",
287 "InstallDir", VSInstallPath, nullptr)) {
288 if (!VSInstallPath.empty()) {
289 llvm::SmallString<256> VCPath(llvm::StringRef(
290 VSInstallPath.c_str(), VSInstallPath.find(R"(\Common7\IDE)")));
291 llvm::sys::path::append(VCPath, "VC");
292
293 Path = VCPath.str();
Stephan T. Lavavej4c30b742017-08-21 22:19:33 +0000294 VSLayout = MSVCToolChain::ToolsetLayout::OlderVS;
Zachary Turnerf6302522017-03-15 16:07:35 +0000295 return true;
296 }
297 }
298 return false;
299}
300
David L. Jonesf561aba2017-03-08 01:02:16 +0000301// Try to find Exe from a Visual Studio distribution. This first tries to find
302// an installed copy of Visual Studio and, failing that, looks in the PATH,
303// making sure that whatever executable that's found is not a same-named exe
304// from clang itself to prevent clang from falling back to itself.
305static std::string FindVisualStudioExecutable(const ToolChain &TC,
Zachary Turnerf6302522017-03-15 16:07:35 +0000306 const char *Exe) {
David L. Jonesf561aba2017-03-08 01:02:16 +0000307 const auto &MSVC = static_cast<const toolchains::MSVCToolChain &>(TC);
Zachary Turnerf6302522017-03-15 16:07:35 +0000308 SmallString<128> FilePath(MSVC.getSubDirectoryPath(
309 toolchains::MSVCToolChain::SubDirectoryType::Bin));
310 llvm::sys::path::append(FilePath, Exe);
311 return llvm::sys::fs::can_execute(FilePath) ? FilePath.str() : Exe;
David L. Jonesf561aba2017-03-08 01:02:16 +0000312}
313
314void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA,
315 const InputInfo &Output,
316 const InputInfoList &Inputs,
317 const ArgList &Args,
318 const char *LinkingOutput) const {
319 ArgStringList CmdArgs;
Zachary Turnerf6302522017-03-15 16:07:35 +0000320
321 auto &TC = static_cast<const toolchains::MSVCToolChain &>(getToolChain());
David L. Jonesf561aba2017-03-08 01:02:16 +0000322
323 assert((Output.isFilename() || Output.isNothing()) && "invalid output");
324 if (Output.isFilename())
325 CmdArgs.push_back(
326 Args.MakeArgString(std::string("-out:") + Output.getFilename()));
327
328 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles) &&
329 !C.getDriver().IsCLMode())
330 CmdArgs.push_back("-defaultlib:libcmt");
331
332 if (!llvm::sys::Process::GetEnv("LIB")) {
333 // If the VC environment hasn't been configured (perhaps because the user
334 // did not run vcvarsall), try to build a consistent link environment. If
335 // the environment variable is set however, assume the user knows what
336 // they're doing.
Zachary Turnerf6302522017-03-15 16:07:35 +0000337 CmdArgs.push_back(Args.MakeArgString(
338 Twine("-libpath:") +
339 TC.getSubDirectoryPath(
340 toolchains::MSVCToolChain::SubDirectoryType::Lib)));
David L. Jonesf561aba2017-03-08 01:02:16 +0000341
Zachary Turnerf6302522017-03-15 16:07:35 +0000342 if (TC.useUniversalCRT()) {
343 std::string UniversalCRTLibPath;
344 if (TC.getUniversalCRTLibraryPath(UniversalCRTLibPath))
345 CmdArgs.push_back(
346 Args.MakeArgString(Twine("-libpath:") + UniversalCRTLibPath));
David L. Jonesf561aba2017-03-08 01:02:16 +0000347 }
348
349 std::string WindowsSdkLibPath;
Zachary Turnerf6302522017-03-15 16:07:35 +0000350 if (TC.getWindowsSDKLibraryPath(WindowsSdkLibPath))
David L. Jonesf561aba2017-03-08 01:02:16 +0000351 CmdArgs.push_back(
352 Args.MakeArgString(std::string("-libpath:") + WindowsSdkLibPath));
353 }
354
355 if (!C.getDriver().IsCLMode() && Args.hasArg(options::OPT_L))
356 for (const auto &LibPath : Args.getAllArgValues(options::OPT_L))
357 CmdArgs.push_back(Args.MakeArgString("-libpath:" + LibPath));
358
359 CmdArgs.push_back("-nologo");
360
361 if (Args.hasArg(options::OPT_g_Group, options::OPT__SLASH_Z7,
362 options::OPT__SLASH_Zd))
363 CmdArgs.push_back("-debug");
364
365 bool DLL = Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd,
366 options::OPT_shared);
367 if (DLL) {
368 CmdArgs.push_back(Args.MakeArgString("-dll"));
369
370 SmallString<128> ImplibName(Output.getFilename());
371 llvm::sys::path::replace_extension(ImplibName, "lib");
Zachary Turner41a9ee92017-10-11 23:54:34 +0000372 CmdArgs.push_back(Args.MakeArgString(std::string("-implib:") + ImplibName));
David L. Jonesf561aba2017-03-08 01:02:16 +0000373 }
374
375 if (TC.getSanitizerArgs().needsAsanRt()) {
376 CmdArgs.push_back(Args.MakeArgString("-debug"));
377 CmdArgs.push_back(Args.MakeArgString("-incremental:no"));
Evgeniy Stepanov0876cfb2017-10-05 20:14:00 +0000378 if (TC.getSanitizerArgs().needsSharedRt() ||
David L. Jonesf561aba2017-03-08 01:02:16 +0000379 Args.hasArg(options::OPT__SLASH_MD, options::OPT__SLASH_MDd)) {
380 for (const auto &Lib : {"asan_dynamic", "asan_dynamic_runtime_thunk"})
381 CmdArgs.push_back(TC.getCompilerRTArgString(Args, Lib));
382 // Make sure the dynamic runtime thunk is not optimized out at link time
383 // to ensure proper SEH handling.
384 CmdArgs.push_back(Args.MakeArgString(
385 TC.getArch() == llvm::Triple::x86
386 ? "-include:___asan_seh_interceptor"
387 : "-include:__asan_seh_interceptor"));
388 // Make sure the linker consider all object files from the dynamic runtime
389 // thunk.
390 CmdArgs.push_back(Args.MakeArgString(std::string("-wholearchive:") +
391 TC.getCompilerRT(Args, "asan_dynamic_runtime_thunk")));
392 } else if (DLL) {
393 CmdArgs.push_back(TC.getCompilerRTArgString(Args, "asan_dll_thunk"));
394 } else {
395 for (const auto &Lib : {"asan", "asan_cxx"}) {
396 CmdArgs.push_back(TC.getCompilerRTArgString(Args, Lib));
397 // Make sure the linker consider all object files from the static lib.
398 // This is necessary because instrumented dlls need access to all the
399 // interface exported by the static lib in the main executable.
400 CmdArgs.push_back(Args.MakeArgString(std::string("-wholearchive:") +
401 TC.getCompilerRT(Args, Lib)));
402 }
403 }
404 }
405
406 Args.AddAllArgValues(CmdArgs, options::OPT__SLASH_link);
407
408 if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
409 options::OPT_fno_openmp, false)) {
410 CmdArgs.push_back("-nodefaultlib:vcomp.lib");
411 CmdArgs.push_back("-nodefaultlib:vcompd.lib");
412 CmdArgs.push_back(Args.MakeArgString(std::string("-libpath:") +
413 TC.getDriver().Dir + "/../lib"));
414 switch (TC.getDriver().getOpenMPRuntime(Args)) {
415 case Driver::OMPRT_OMP:
416 CmdArgs.push_back("-defaultlib:libomp.lib");
417 break;
418 case Driver::OMPRT_IOMP5:
419 CmdArgs.push_back("-defaultlib:libiomp5md.lib");
420 break;
421 case Driver::OMPRT_GOMP:
422 break;
423 case Driver::OMPRT_Unknown:
424 // Already diagnosed.
425 break;
426 }
427 }
428
429 // Add compiler-rt lib in case if it was explicitly
430 // specified as an argument for --rtlib option.
431 if (!Args.hasArg(options::OPT_nostdlib)) {
432 AddRunTimeLibs(TC, TC.getDriver(), CmdArgs, Args);
433 }
434
435 // Add filenames, libraries, and other linker inputs.
436 for (const auto &Input : Inputs) {
437 if (Input.isFilename()) {
438 CmdArgs.push_back(Input.getFilename());
439 continue;
440 }
441
442 const Arg &A = Input.getInputArg();
443
444 // Render -l options differently for the MSVC linker.
445 if (A.getOption().matches(options::OPT_l)) {
446 StringRef Lib = A.getValue();
447 const char *LinkLibArg;
448 if (Lib.endswith(".lib"))
449 LinkLibArg = Args.MakeArgString(Lib);
450 else
451 LinkLibArg = Args.MakeArgString(Lib + ".lib");
452 CmdArgs.push_back(LinkLibArg);
453 continue;
454 }
455
456 // Otherwise, this is some other kind of linker input option like -Wl, -z,
457 // or -L. Render it, even if MSVC doesn't understand it.
458 A.renderAsInput(Args, CmdArgs);
459 }
460
461 TC.addProfileRTLibs(Args, CmdArgs);
462
Zachary Turnera0f96be2017-03-17 16:24:34 +0000463 std::vector<const char *> Environment;
464
David L. Jonesf561aba2017-03-08 01:02:16 +0000465 // We need to special case some linker paths. In the case of lld, we need to
466 // translate 'lld' into 'lld-link', and in the case of the regular msvc
467 // linker, we need to use a special search algorithm.
468 llvm::SmallString<128> linkPath;
469 StringRef Linker = Args.getLastArgValue(options::OPT_fuse_ld_EQ, "link");
470 if (Linker.equals_lower("lld"))
471 Linker = "lld-link";
472
473 if (Linker.equals_lower("link")) {
474 // If we're using the MSVC linker, it's not sufficient to just use link
475 // from the program PATH, because other environments like GnuWin32 install
476 // their own link.exe which may come first.
Zachary Turnerf6302522017-03-15 16:07:35 +0000477 linkPath = FindVisualStudioExecutable(TC, "link.exe");
Zachary Turnera0f96be2017-03-17 16:24:34 +0000478
479#ifdef USE_WIN32
480 // When cross-compiling with VS2017 or newer, link.exe expects to have
481 // its containing bin directory at the top of PATH, followed by the
482 // native target bin directory.
483 // e.g. when compiling for x86 on an x64 host, PATH should start with:
484 // /bin/HostX64/x86;/bin/HostX64/x64
Stephan T. Lavavej4c30b742017-08-21 22:19:33 +0000485 // This doesn't attempt to handle ToolsetLayout::DevDivInternal.
Zachary Turnera0f96be2017-03-17 16:24:34 +0000486 if (TC.getIsVS2017OrNewer() &&
487 llvm::Triple(llvm::sys::getProcessTriple()).getArch() != TC.getArch()) {
488 auto HostArch = llvm::Triple(llvm::sys::getProcessTriple()).getArch();
489
490 auto EnvBlockWide =
491 std::unique_ptr<wchar_t[], decltype(&FreeEnvironmentStringsW)>(
492 GetEnvironmentStringsW(), FreeEnvironmentStringsW);
493 if (!EnvBlockWide)
494 goto SkipSettingEnvironment;
495
496 size_t EnvCount = 0;
497 size_t EnvBlockLen = 0;
498 while (EnvBlockWide[EnvBlockLen] != L'\0') {
499 ++EnvCount;
500 EnvBlockLen += std::wcslen(&EnvBlockWide[EnvBlockLen]) +
501 1 /*string null-terminator*/;
502 }
503 ++EnvBlockLen; // add the block null-terminator
504
505 std::string EnvBlock;
506 if (!llvm::convertUTF16ToUTF8String(
507 llvm::ArrayRef<char>(reinterpret_cast<char *>(EnvBlockWide.get()),
508 EnvBlockLen * sizeof(EnvBlockWide[0])),
509 EnvBlock))
510 goto SkipSettingEnvironment;
511
512 Environment.reserve(EnvCount);
513
514 // Now loop over each string in the block and copy them into the
515 // environment vector, adjusting the PATH variable as needed when we
516 // find it.
517 for (const char *Cursor = EnvBlock.data(); *Cursor != '\0';) {
518 llvm::StringRef EnvVar(Cursor);
519 if (EnvVar.startswith_lower("path=")) {
520 using SubDirectoryType = toolchains::MSVCToolChain::SubDirectoryType;
521 constexpr size_t PrefixLen = 5; // strlen("path=")
522 Environment.push_back(Args.MakeArgString(
523 EnvVar.substr(0, PrefixLen) +
524 TC.getSubDirectoryPath(SubDirectoryType::Bin) +
525 llvm::Twine(llvm::sys::EnvPathSeparator) +
526 TC.getSubDirectoryPath(SubDirectoryType::Bin, HostArch) +
527 (EnvVar.size() > PrefixLen
528 ? llvm::Twine(llvm::sys::EnvPathSeparator) +
529 EnvVar.substr(PrefixLen)
530 : "")));
531 } else {
532 Environment.push_back(Args.MakeArgString(EnvVar));
533 }
534 Cursor += EnvVar.size() + 1 /*null-terminator*/;
535 }
536 }
537 SkipSettingEnvironment:;
538#endif
David L. Jonesf561aba2017-03-08 01:02:16 +0000539 } else {
Shoaib Meenai462f36d2017-06-06 02:06:28 +0000540 linkPath = TC.GetProgramPath(Linker.str().c_str());
David L. Jonesf561aba2017-03-08 01:02:16 +0000541 }
542
Zachary Turnera0f96be2017-03-17 16:24:34 +0000543 auto LinkCmd = llvm::make_unique<Command>(
544 JA, *this, Args.MakeArgString(linkPath), CmdArgs, Inputs);
545 if (!Environment.empty())
546 LinkCmd->setEnvironment(Environment);
547 C.addCommand(std::move(LinkCmd));
David L. Jonesf561aba2017-03-08 01:02:16 +0000548}
549
550void visualstudio::Compiler::ConstructJob(Compilation &C, const JobAction &JA,
551 const InputInfo &Output,
552 const InputInfoList &Inputs,
553 const ArgList &Args,
554 const char *LinkingOutput) const {
555 C.addCommand(GetCommand(C, JA, Output, Inputs, Args, LinkingOutput));
556}
557
558std::unique_ptr<Command> visualstudio::Compiler::GetCommand(
559 Compilation &C, const JobAction &JA, const InputInfo &Output,
560 const InputInfoList &Inputs, const ArgList &Args,
561 const char *LinkingOutput) const {
562 ArgStringList CmdArgs;
563 CmdArgs.push_back("/nologo");
564 CmdArgs.push_back("/c"); // Compile only.
565 CmdArgs.push_back("/W0"); // No warnings.
566
567 // The goal is to be able to invoke this tool correctly based on
568 // any flag accepted by clang-cl.
569
570 // These are spelled the same way in clang and cl.exe,.
571 Args.AddAllArgs(CmdArgs, {options::OPT_D, options::OPT_U, options::OPT_I});
572
573 // Optimization level.
574 if (Arg *A = Args.getLastArg(options::OPT_fbuiltin, options::OPT_fno_builtin))
575 CmdArgs.push_back(A->getOption().getID() == options::OPT_fbuiltin ? "/Oi"
576 : "/Oi-");
577 if (Arg *A = Args.getLastArg(options::OPT_O, options::OPT_O0)) {
578 if (A->getOption().getID() == options::OPT_O0) {
579 CmdArgs.push_back("/Od");
580 } else {
581 CmdArgs.push_back("/Og");
582
583 StringRef OptLevel = A->getValue();
584 if (OptLevel == "s" || OptLevel == "z")
585 CmdArgs.push_back("/Os");
586 else
587 CmdArgs.push_back("/Ot");
588
589 CmdArgs.push_back("/Ob2");
590 }
591 }
592 if (Arg *A = Args.getLastArg(options::OPT_fomit_frame_pointer,
593 options::OPT_fno_omit_frame_pointer))
594 CmdArgs.push_back(A->getOption().getID() == options::OPT_fomit_frame_pointer
595 ? "/Oy"
596 : "/Oy-");
597 if (!Args.hasArg(options::OPT_fwritable_strings))
598 CmdArgs.push_back("/GF");
599
600 // Flags for which clang-cl has an alias.
601 // FIXME: How can we ensure this stays in sync with relevant clang-cl options?
602
603 if (Args.hasFlag(options::OPT__SLASH_GR_, options::OPT__SLASH_GR,
604 /*default=*/false))
605 CmdArgs.push_back("/GR-");
606
607 if (Args.hasFlag(options::OPT__SLASH_GS_, options::OPT__SLASH_GS,
608 /*default=*/false))
609 CmdArgs.push_back("/GS-");
610
611 if (Arg *A = Args.getLastArg(options::OPT_ffunction_sections,
612 options::OPT_fno_function_sections))
613 CmdArgs.push_back(A->getOption().getID() == options::OPT_ffunction_sections
614 ? "/Gy"
615 : "/Gy-");
616 if (Arg *A = Args.getLastArg(options::OPT_fdata_sections,
617 options::OPT_fno_data_sections))
618 CmdArgs.push_back(
619 A->getOption().getID() == options::OPT_fdata_sections ? "/Gw" : "/Gw-");
620 if (Args.hasArg(options::OPT_fsyntax_only))
621 CmdArgs.push_back("/Zs");
622 if (Args.hasArg(options::OPT_g_Flag, options::OPT_gline_tables_only,
623 options::OPT__SLASH_Z7))
624 CmdArgs.push_back("/Z7");
625
626 std::vector<std::string> Includes =
627 Args.getAllArgValues(options::OPT_include);
628 for (const auto &Include : Includes)
629 CmdArgs.push_back(Args.MakeArgString(std::string("/FI") + Include));
630
631 // Flags that can simply be passed through.
632 Args.AddAllArgs(CmdArgs, options::OPT__SLASH_LD);
633 Args.AddAllArgs(CmdArgs, options::OPT__SLASH_LDd);
634 Args.AddAllArgs(CmdArgs, options::OPT__SLASH_GX);
635 Args.AddAllArgs(CmdArgs, options::OPT__SLASH_GX_);
636 Args.AddAllArgs(CmdArgs, options::OPT__SLASH_EH);
637 Args.AddAllArgs(CmdArgs, options::OPT__SLASH_Zl);
638
639 // The order of these flags is relevant, so pick the last one.
640 if (Arg *A = Args.getLastArg(options::OPT__SLASH_MD, options::OPT__SLASH_MDd,
641 options::OPT__SLASH_MT, options::OPT__SLASH_MTd))
642 A->render(Args, CmdArgs);
643
644 // Use MSVC's default threadsafe statics behaviour unless there was a flag.
645 if (Arg *A = Args.getLastArg(options::OPT_fthreadsafe_statics,
646 options::OPT_fno_threadsafe_statics)) {
647 CmdArgs.push_back(A->getOption().getID() == options::OPT_fthreadsafe_statics
648 ? "/Zc:threadSafeInit"
649 : "/Zc:threadSafeInit-");
650 }
651
652 // Pass through all unknown arguments so that the fallback command can see
653 // them too.
654 Args.AddAllArgs(CmdArgs, options::OPT_UNKNOWN);
655
656 // Input filename.
657 assert(Inputs.size() == 1);
658 const InputInfo &II = Inputs[0];
659 assert(II.getType() == types::TY_C || II.getType() == types::TY_CXX);
660 CmdArgs.push_back(II.getType() == types::TY_C ? "/Tc" : "/Tp");
661 if (II.isFilename())
662 CmdArgs.push_back(II.getFilename());
663 else
664 II.getInputArg().renderAsInput(Args, CmdArgs);
665
666 // Output filename.
667 assert(Output.getType() == types::TY_Object);
668 const char *Fo =
669 Args.MakeArgString(std::string("/Fo") + Output.getFilename());
670 CmdArgs.push_back(Fo);
671
Zachary Turnerf6302522017-03-15 16:07:35 +0000672 std::string Exec = FindVisualStudioExecutable(getToolChain(), "cl.exe");
David L. Jonesf561aba2017-03-08 01:02:16 +0000673 return llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Exec),
674 CmdArgs, Inputs);
675}
676
Reid Klecknerbf183552017-02-02 19:36:22 +0000677MSVCToolChain::MSVCToolChain(const Driver &D, const llvm::Triple &Triple,
Saleem Abdulrasool819f3912014-10-22 02:37:29 +0000678 const ArgList &Args)
Justin Lebar58891902017-01-05 16:52:29 +0000679 : ToolChain(D, Triple, Args), CudaInstallation(D, Triple, Args) {
Zachary Turner719f58c2014-12-01 23:06:47 +0000680 getProgramPaths().push_back(getDriver().getInstalledDir());
681 if (getDriver().getInstalledDir() != getDriver().Dir)
682 getProgramPaths().push_back(getDriver().Dir);
Zachary Turnerf6302522017-03-15 16:07:35 +0000683
684 // Check the environment first, since that's probably the user telling us
685 // what they want to use.
686 // Failing that, just try to find the newest Visual Studio version we can
687 // and use its default VC toolchain.
Stephan T. Lavavej4c30b742017-08-21 22:19:33 +0000688 findVCToolChainViaEnvironment(VCToolChainPath, VSLayout) ||
689 findVCToolChainViaSetupConfig(VCToolChainPath, VSLayout) ||
690 findVCToolChainViaRegistry(VCToolChainPath, VSLayout);
Hans Wennborg1cc6cce2013-08-30 09:42:06 +0000691}
692
Saleem Abdulrasool819f3912014-10-22 02:37:29 +0000693Tool *MSVCToolChain::buildLinker() const {
Zachary Turnerf6302522017-03-15 16:07:35 +0000694 if (VCToolChainPath.empty())
695 getDriver().Diag(clang::diag::warn_drv_msvc_not_found);
Douglas Katzman95354292015-06-23 20:42:09 +0000696 return new tools::visualstudio::Linker(*this);
Hans Wennborg1cc6cce2013-08-30 09:42:06 +0000697}
698
Saleem Abdulrasool819f3912014-10-22 02:37:29 +0000699Tool *MSVCToolChain::buildAssembler() const {
Saleem Abdulrasool377066a2014-03-27 22:50:18 +0000700 if (getTriple().isOSBinFormatMachO())
Douglas Katzman95354292015-06-23 20:42:09 +0000701 return new tools::darwin::Assembler(*this);
Alp Tokerc8d4f0f2013-11-22 08:27:46 +0000702 getDriver().Diag(clang::diag::err_no_external_assembler);
Craig Topper92fc2df2014-05-17 16:56:41 +0000703 return nullptr;
Hans Wennborg1cc6cce2013-08-30 09:42:06 +0000704}
705
Saleem Abdulrasool819f3912014-10-22 02:37:29 +0000706bool MSVCToolChain::IsIntegratedAssemblerDefault() const {
Hans Wennborg1cc6cce2013-08-30 09:42:06 +0000707 return true;
708}
709
Akira Hatanakab72e35a2017-08-03 23:55:42 +0000710bool MSVCToolChain::IsUnwindTablesDefault(const ArgList &Args) const {
Reid Kleckner6b3a9402014-09-04 18:13:12 +0000711 // Emit unwind tables by default on Win64. All non-x86_32 Windows platforms
712 // such as ARM and PPC actually require unwind tables, but LLVM doesn't know
713 // how to generate them yet.
Akira Hatanakae4218132016-05-05 01:41:07 +0000714
715 // Don't emit unwind tables by default for MachO targets.
716 if (getTriple().isOSBinFormatMachO())
717 return false;
718
Reid Kleckner6b3a9402014-09-04 18:13:12 +0000719 return getArch() == llvm::Triple::x86_64;
Hans Wennborg1cc6cce2013-08-30 09:42:06 +0000720}
721
Reid Kleckner8c190832016-12-28 17:41:36 +0000722bool MSVCToolChain::isPICDefault() const {
723 return getArch() == llvm::Triple::x86_64;
724}
725
726bool MSVCToolChain::isPIEDefault() const {
727 return false;
728}
729
730bool MSVCToolChain::isPICDefaultForced() const {
731 return getArch() == llvm::Triple::x86_64;
732}
733
Justin Lebar58891902017-01-05 16:52:29 +0000734void MSVCToolChain::AddCudaIncludeArgs(const ArgList &DriverArgs,
735 ArgStringList &CC1Args) const {
736 CudaInstallation.AddCudaIncludeArgs(DriverArgs, CC1Args);
737}
738
739void MSVCToolChain::printVerboseInfo(raw_ostream &OS) const {
740 CudaInstallation.print(OS);
741}
742
Zachary Turnerf6302522017-03-15 16:07:35 +0000743// Windows SDKs and VC Toolchains group their contents into subdirectories based
744// on the target architecture. This function converts an llvm::Triple::ArchType
745// to the corresponding subdirectory name.
746static const char *llvmArchToWindowsSDKArch(llvm::Triple::ArchType Arch) {
747 using ArchType = llvm::Triple::ArchType;
748 switch (Arch) {
749 case ArchType::x86:
750 return "x86";
751 case ArchType::x86_64:
752 return "x64";
753 case ArchType::arm:
754 return "arm";
755 default:
756 return "";
757 }
758}
759
760// Similar to the above function, but for Visual Studios before VS2017.
761static const char *llvmArchToLegacyVCArch(llvm::Triple::ArchType Arch) {
762 using ArchType = llvm::Triple::ArchType;
763 switch (Arch) {
764 case ArchType::x86:
765 // x86 is default in legacy VC toolchains.
766 // e.g. x86 libs are directly in /lib as opposed to /lib/x86.
767 return "";
768 case ArchType::x86_64:
769 return "amd64";
770 case ArchType::arm:
771 return "arm";
772 default:
773 return "";
774 }
775}
776
Stephan T. Lavavej4c30b742017-08-21 22:19:33 +0000777// Similar to the above function, but for DevDiv internal builds.
778static const char *llvmArchToDevDivInternalArch(llvm::Triple::ArchType Arch) {
779 using ArchType = llvm::Triple::ArchType;
780 switch (Arch) {
781 case ArchType::x86:
782 return "i386";
783 case ArchType::x86_64:
784 return "amd64";
785 case ArchType::arm:
786 return "arm";
787 default:
788 return "";
789 }
790}
791
Zachary Turnerf6302522017-03-15 16:07:35 +0000792// Get the path to a specific subdirectory in the current toolchain for
793// a given target architecture.
794// VS2017 changed the VC toolchain layout, so this should be used instead
795// of hardcoding paths.
796std::string
797MSVCToolChain::getSubDirectoryPath(SubDirectoryType Type,
798 llvm::Triple::ArchType TargetArch) const {
Stephan T. Lavavej4c30b742017-08-21 22:19:33 +0000799 const char *SubdirName;
800 const char *IncludeName;
801 switch (VSLayout) {
802 case ToolsetLayout::OlderVS:
803 SubdirName = llvmArchToLegacyVCArch(TargetArch);
804 IncludeName = "include";
805 break;
806 case ToolsetLayout::VS2017OrNewer:
807 SubdirName = llvmArchToWindowsSDKArch(TargetArch);
808 IncludeName = "include";
809 break;
810 case ToolsetLayout::DevDivInternal:
811 SubdirName = llvmArchToDevDivInternalArch(TargetArch);
812 IncludeName = "inc";
813 break;
814 }
815
Zachary Turnerf6302522017-03-15 16:07:35 +0000816 llvm::SmallString<256> Path(VCToolChainPath);
817 switch (Type) {
818 case SubDirectoryType::Bin:
Stephan T. Lavavej4c30b742017-08-21 22:19:33 +0000819 if (VSLayout == ToolsetLayout::VS2017OrNewer) {
820 const bool HostIsX64 =
Zachary Turnerf6302522017-03-15 16:07:35 +0000821 llvm::Triple(llvm::sys::getProcessTriple()).isArch64Bit();
Stephan T. Lavavej4c30b742017-08-21 22:19:33 +0000822 const char *const HostName = HostIsX64 ? "HostX64" : "HostX86";
823 llvm::sys::path::append(Path, "bin", HostName, SubdirName);
824 } else { // OlderVS or DevDivInternal
825 llvm::sys::path::append(Path, "bin", SubdirName);
Zachary Turnerf6302522017-03-15 16:07:35 +0000826 }
827 break;
828 case SubDirectoryType::Include:
Stephan T. Lavavej4c30b742017-08-21 22:19:33 +0000829 llvm::sys::path::append(Path, IncludeName);
Zachary Turnerf6302522017-03-15 16:07:35 +0000830 break;
831 case SubDirectoryType::Lib:
Stephan T. Lavavej4c30b742017-08-21 22:19:33 +0000832 llvm::sys::path::append(Path, "lib", SubdirName);
Zachary Turnerf6302522017-03-15 16:07:35 +0000833 break;
834 }
835 return Path.str();
836}
837
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000838#ifdef USE_WIN32
839static bool readFullStringValue(HKEY hkey, const char *valueName,
840 std::string &value) {
Aaron Ballmanb06a3592016-06-23 14:33:53 +0000841 std::wstring WideValueName;
842 if (!llvm::ConvertUTF8toWide(valueName, WideValueName))
843 return false;
844
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000845 DWORD result = 0;
846 DWORD valueSize = 0;
847 DWORD type = 0;
848 // First just query for the required size.
Aaron Ballmanb06a3592016-06-23 14:33:53 +0000849 result = RegQueryValueExW(hkey, WideValueName.c_str(), NULL, &type, NULL,
850 &valueSize);
851 if (result != ERROR_SUCCESS || type != REG_SZ || !valueSize)
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000852 return false;
853 std::vector<BYTE> buffer(valueSize);
Aaron Ballmanb06a3592016-06-23 14:33:53 +0000854 result = RegQueryValueExW(hkey, WideValueName.c_str(), NULL, NULL, &buffer[0],
855 &valueSize);
856 if (result == ERROR_SUCCESS) {
857 std::wstring WideValue(reinterpret_cast<const wchar_t *>(buffer.data()),
858 valueSize / sizeof(wchar_t));
Zachary Turnere78a3472016-07-28 17:13:32 +0000859 if (valueSize && WideValue.back() == L'\0') {
Etienne Bergeron982a3bc2016-08-30 18:38:25 +0000860 WideValue.pop_back();
Zachary Turnere78a3472016-07-28 17:13:32 +0000861 }
Aaron Ballmanb06a3592016-06-23 14:33:53 +0000862 // The destination buffer must be empty as an invariant of the conversion
863 // function; but this function is sometimes called in a loop that passes in
864 // the same buffer, however. Simply clear it out so we can overwrite it.
865 value.clear();
866 return llvm::convertWideToUTF8(WideValue, value);
867 }
868 return false;
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000869}
870#endif
871
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000872/// \brief Read registry string.
873/// This also supports a means to look for high-versioned keys by use
874/// of a $VERSION placeholder in the key path.
875/// $VERSION in the key path is a placeholder for the version number,
876/// causing the highest value path to be searched for and used.
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000877/// I.e. "SOFTWARE\\Microsoft\\VisualStudio\\$VERSION".
878/// There can be additional characters in the component. Only the numeric
879/// characters are compared. This function only searches HKLM.
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000880static bool getSystemRegistryString(const char *keyPath, const char *valueName,
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000881 std::string &value, std::string *phValue) {
Alp Tokerfcce1832014-06-22 03:27:45 +0000882#ifndef USE_WIN32
883 return false;
884#else
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000885 HKEY hRootKey = HKEY_LOCAL_MACHINE;
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000886 HKEY hKey = NULL;
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000887 long lResult;
888 bool returnValue = false;
889
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000890 const char *placeHolder = strstr(keyPath, "$VERSION");
891 std::string bestName;
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000892 // If we have a $VERSION placeholder, do the highest-version search.
893 if (placeHolder) {
894 const char *keyEnd = placeHolder - 1;
895 const char *nextKey = placeHolder;
896 // Find end of previous key.
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000897 while ((keyEnd > keyPath) && (*keyEnd != '\\'))
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000898 keyEnd--;
899 // Find end of key containing $VERSION.
900 while (*nextKey && (*nextKey != '\\'))
901 nextKey++;
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000902 size_t partialKeyLength = keyEnd - keyPath;
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000903 char partialKey[256];
Daniel Marjamakie1146692016-01-27 07:33:50 +0000904 if (partialKeyLength >= sizeof(partialKey))
905 partialKeyLength = sizeof(partialKey) - 1;
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000906 strncpy(partialKey, keyPath, partialKeyLength);
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000907 partialKey[partialKeyLength] = '\0';
908 HKEY hTopKey = NULL;
Aaron Ballmanb06a3592016-06-23 14:33:53 +0000909 lResult = RegOpenKeyExA(hRootKey, partialKey, 0, KEY_READ | KEY_WOW64_32KEY,
910 &hTopKey);
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000911 if (lResult == ERROR_SUCCESS) {
912 char keyName[256];
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000913 double bestValue = 0.0;
914 DWORD index, size = sizeof(keyName) - 1;
Aaron Ballmanb06a3592016-06-23 14:33:53 +0000915 for (index = 0; RegEnumKeyExA(hTopKey, index, keyName, &size, NULL, NULL,
916 NULL, NULL) == ERROR_SUCCESS;
917 index++) {
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000918 const char *sp = keyName;
Jordan Rosea7d03842013-02-08 22:30:41 +0000919 while (*sp && !isDigit(*sp))
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000920 sp++;
921 if (!*sp)
922 continue;
923 const char *ep = sp + 1;
Jordan Rosea7d03842013-02-08 22:30:41 +0000924 while (*ep && (isDigit(*ep) || (*ep == '.')))
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000925 ep++;
926 char numBuf[32];
927 strncpy(numBuf, sp, sizeof(numBuf) - 1);
928 numBuf[sizeof(numBuf) - 1] = '\0';
Hans Wennborgd2192312013-10-10 18:03:08 +0000929 double dvalue = strtod(numBuf, NULL);
930 if (dvalue > bestValue) {
931 // Test that InstallDir is indeed there before keeping this index.
932 // Open the chosen key path remainder.
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000933 bestName = keyName;
Hans Wennborgd2192312013-10-10 18:03:08 +0000934 // Append rest of key.
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000935 bestName.append(nextKey);
Aaron Ballmanb06a3592016-06-23 14:33:53 +0000936 lResult = RegOpenKeyExA(hTopKey, bestName.c_str(), 0,
937 KEY_READ | KEY_WOW64_32KEY, &hKey);
Hans Wennborgd2192312013-10-10 18:03:08 +0000938 if (lResult == ERROR_SUCCESS) {
Zachary Turnere78a3472016-07-28 17:13:32 +0000939 if (readFullStringValue(hKey, valueName, value)) {
Hans Wennborgd2192312013-10-10 18:03:08 +0000940 bestValue = dvalue;
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000941 if (phValue)
942 *phValue = bestName;
Hans Wennborgd2192312013-10-10 18:03:08 +0000943 returnValue = true;
944 }
945 RegCloseKey(hKey);
946 }
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000947 }
948 size = sizeof(keyName) - 1;
949 }
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000950 RegCloseKey(hTopKey);
951 }
952 } else {
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000953 lResult =
Aaron Ballmanb06a3592016-06-23 14:33:53 +0000954 RegOpenKeyExA(hRootKey, keyPath, 0, KEY_READ | KEY_WOW64_32KEY, &hKey);
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000955 if (lResult == ERROR_SUCCESS) {
Zachary Turnere78a3472016-07-28 17:13:32 +0000956 if (readFullStringValue(hKey, valueName, value))
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000957 returnValue = true;
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000958 if (phValue)
959 phValue->clear();
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000960 RegCloseKey(hKey);
961 }
962 }
963 return returnValue;
Alp Tokerfcce1832014-06-22 03:27:45 +0000964#endif // USE_WIN32
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000965}
966
Igor Kudrinf2e75242015-09-24 05:16:36 +0000967// Find the most recent version of Universal CRT or Windows 10 SDK.
968// vcvarsqueryregistry.bat from Visual Studio 2015 sorts entries in the include
969// directory by name and uses the last one of the list.
970// So we compare entry names lexicographically to find the greatest one.
Zachary Turnerf6302522017-03-15 16:07:35 +0000971static bool getWindows10SDKVersionFromPath(const std::string &SDKPath,
972 std::string &SDKVersion) {
Igor Kudrinf2e75242015-09-24 05:16:36 +0000973 SDKVersion.clear();
974
975 std::error_code EC;
976 llvm::SmallString<128> IncludePath(SDKPath);
977 llvm::sys::path::append(IncludePath, "Include");
978 for (llvm::sys::fs::directory_iterator DirIt(IncludePath, EC), DirEnd;
979 DirIt != DirEnd && !EC; DirIt.increment(EC)) {
980 if (!llvm::sys::fs::is_directory(DirIt->path()))
981 continue;
982 StringRef CandidateName = llvm::sys::path::filename(DirIt->path());
983 // If WDK is installed, there could be subfolders like "wdf" in the
984 // "Include" directory.
985 // Allow only directories which names start with "10.".
986 if (!CandidateName.startswith("10."))
987 continue;
988 if (CandidateName > SDKVersion)
989 SDKVersion = CandidateName;
990 }
991
992 return !SDKVersion.empty();
993}
994
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000995/// \brief Get Windows SDK installation directory.
Zachary Turnerf6302522017-03-15 16:07:35 +0000996static bool getWindowsSDKDir(std::string &Path, int &Major,
997 std::string &WindowsSDKIncludeVersion,
998 std::string &WindowsSDKLibVersion) {
Igor Kudrinf2e75242015-09-24 05:16:36 +0000999 std::string RegistrySDKVersion;
Chandler Carruth1fc603e2011-12-17 23:10:01 +00001000 // Try the Windows registry.
Igor Kudrinf2e75242015-09-24 05:16:36 +00001001 if (!getSystemRegistryString(
1002 "SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\$VERSION",
1003 "InstallationFolder", Path, &RegistrySDKVersion))
1004 return false;
1005 if (Path.empty() || RegistrySDKVersion.empty())
1006 return false;
1007
1008 WindowsSDKIncludeVersion.clear();
1009 WindowsSDKLibVersion.clear();
1010 Major = 0;
1011 std::sscanf(RegistrySDKVersion.c_str(), "v%d.", &Major);
1012 if (Major <= 7)
1013 return true;
1014 if (Major == 8) {
1015 // Windows SDK 8.x installs libraries in a folder whose names depend on the
1016 // version of the OS you're targeting. By default choose the newest, which
1017 // usually corresponds to the version of the OS you've installed the SDK on.
1018 const char *Tests[] = {"winv6.3", "win8", "win7"};
1019 for (const char *Test : Tests) {
1020 llvm::SmallString<128> TestPath(Path);
1021 llvm::sys::path::append(TestPath, "Lib", Test);
1022 if (llvm::sys::fs::exists(TestPath.c_str())) {
1023 WindowsSDKLibVersion = Test;
1024 break;
1025 }
1026 }
1027 return !WindowsSDKLibVersion.empty();
1028 }
1029 if (Major == 10) {
Zachary Turnerf6302522017-03-15 16:07:35 +00001030 if (!getWindows10SDKVersionFromPath(Path, WindowsSDKIncludeVersion))
Igor Kudrinf2e75242015-09-24 05:16:36 +00001031 return false;
1032 WindowsSDKLibVersion = WindowsSDKIncludeVersion;
1033 return true;
1034 }
1035 // Unsupported SDK version
1036 return false;
Zachary Turner0eaf8fc2014-10-22 20:40:28 +00001037}
1038
Zachary Turner10d75b22014-10-22 20:40:43 +00001039// Gets the library path required to link against the Windows SDK.
1040bool MSVCToolChain::getWindowsSDKLibraryPath(std::string &path) const {
1041 std::string sdkPath;
1042 int sdkMajor = 0;
Igor Kudrinf2e75242015-09-24 05:16:36 +00001043 std::string windowsSDKIncludeVersion;
1044 std::string windowsSDKLibVersion;
Zachary Turner10d75b22014-10-22 20:40:43 +00001045
1046 path.clear();
Igor Kudrinf2e75242015-09-24 05:16:36 +00001047 if (!getWindowsSDKDir(sdkPath, sdkMajor, windowsSDKIncludeVersion,
1048 windowsSDKLibVersion))
Zachary Turner10d75b22014-10-22 20:40:43 +00001049 return false;
1050
1051 llvm::SmallString<128> libPath(sdkPath);
1052 llvm::sys::path::append(libPath, "Lib");
Zachary Turnerf6302522017-03-15 16:07:35 +00001053 if (sdkMajor >= 8) {
1054 llvm::sys::path::append(libPath, windowsSDKLibVersion, "um",
1055 llvmArchToWindowsSDKArch(getArch()));
1056 } else {
Zachary Turner10d75b22014-10-22 20:40:43 +00001057 switch (getArch()) {
Reid Klecknerbf183552017-02-02 19:36:22 +00001058 // In Windows SDK 7.x, x86 libraries are directly in the Lib folder.
Zachary Turner10d75b22014-10-22 20:40:43 +00001059 case llvm::Triple::x86:
1060 break;
1061 case llvm::Triple::x86_64:
1062 llvm::sys::path::append(libPath, "x64");
1063 break;
1064 case llvm::Triple::arm:
1065 // It is not necessary to link against Windows SDK 7.x when targeting ARM.
1066 return false;
1067 default:
1068 return false;
1069 }
Zachary Turner10d75b22014-10-22 20:40:43 +00001070 }
1071
1072 path = libPath.str();
1073 return true;
1074}
1075
Reid Kleckner7531f7d2015-09-11 00:09:39 +00001076// Check if the Include path of a specified version of Visual Studio contains
1077// specific header files. If not, they are probably shipped with Universal CRT.
Zachary Turnerf6302522017-03-15 16:07:35 +00001078bool MSVCToolChain::useUniversalCRT() const {
1079 llvm::SmallString<128> TestPath(
1080 getSubDirectoryPath(SubDirectoryType::Include));
1081 llvm::sys::path::append(TestPath, "stdlib.h");
Reid Kleckner7531f7d2015-09-11 00:09:39 +00001082 return !llvm::sys::fs::exists(TestPath);
1083}
1084
Zachary Turnerf6302522017-03-15 16:07:35 +00001085static bool getUniversalCRTSdkDir(std::string &Path, std::string &UCRTVersion) {
Reid Kleckner7531f7d2015-09-11 00:09:39 +00001086 // vcvarsqueryregistry.bat for Visual Studio 2015 queries the registry
1087 // for the specific key "KitsRoot10". So do we.
1088 if (!getSystemRegistryString(
Reid Klecknerbf183552017-02-02 19:36:22 +00001089 "SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots", "KitsRoot10",
1090 Path, nullptr))
Reid Kleckner7531f7d2015-09-11 00:09:39 +00001091 return false;
1092
Zachary Turnerf6302522017-03-15 16:07:35 +00001093 return getWindows10SDKVersionFromPath(Path, UCRTVersion);
Reid Kleckner7531f7d2015-09-11 00:09:39 +00001094}
1095
1096bool MSVCToolChain::getUniversalCRTLibraryPath(std::string &Path) const {
1097 std::string UniversalCRTSdkPath;
1098 std::string UCRTVersion;
1099
1100 Path.clear();
1101 if (!getUniversalCRTSdkDir(UniversalCRTSdkPath, UCRTVersion))
1102 return false;
1103
Zachary Turnerf6302522017-03-15 16:07:35 +00001104 StringRef ArchName = llvmArchToWindowsSDKArch(getArch());
Reid Kleckner7531f7d2015-09-11 00:09:39 +00001105 if (ArchName.empty())
1106 return false;
1107
1108 llvm::SmallString<128> LibPath(UniversalCRTSdkPath);
1109 llvm::sys::path::append(LibPath, "Lib", UCRTVersion, "ucrt", ArchName);
1110
1111 Path = LibPath.str();
1112 return true;
1113}
1114
Zachary Turnerf6302522017-03-15 16:07:35 +00001115static VersionTuple getMSVCVersionFromTriple(const llvm::Triple &Triple) {
David L. Jones24fb20c2016-12-07 23:41:58 +00001116 unsigned Major, Minor, Micro;
Zachary Turnerf6302522017-03-15 16:07:35 +00001117 Triple.getEnvironmentVersion(Major, Minor, Micro);
David L. Jones24fb20c2016-12-07 23:41:58 +00001118 if (Major || Minor || Micro)
1119 return VersionTuple(Major, Minor, Micro);
1120 return VersionTuple();
1121}
1122
Zachary Turnerf6302522017-03-15 16:07:35 +00001123static VersionTuple getMSVCVersionFromExe(const std::string &BinDir) {
Adrian McCarthye4b26fc2016-05-13 23:20:11 +00001124 VersionTuple Version;
1125#ifdef USE_WIN32
Zachary Turnerf6302522017-03-15 16:07:35 +00001126 SmallString<128> ClExe(BinDir);
Adrian McCarthye4b26fc2016-05-13 23:20:11 +00001127 llvm::sys::path::append(ClExe, "cl.exe");
1128
1129 std::wstring ClExeWide;
1130 if (!llvm::ConvertUTF8toWide(ClExe.c_str(), ClExeWide))
1131 return Version;
1132
1133 const DWORD VersionSize = ::GetFileVersionInfoSizeW(ClExeWide.c_str(),
1134 nullptr);
1135 if (VersionSize == 0)
1136 return Version;
1137
1138 SmallVector<uint8_t, 4 * 1024> VersionBlock(VersionSize);
1139 if (!::GetFileVersionInfoW(ClExeWide.c_str(), 0, VersionSize,
1140 VersionBlock.data()))
1141 return Version;
1142
1143 VS_FIXEDFILEINFO *FileInfo = nullptr;
1144 UINT FileInfoSize = 0;
1145 if (!::VerQueryValueW(VersionBlock.data(), L"\\",
1146 reinterpret_cast<LPVOID *>(&FileInfo), &FileInfoSize) ||
1147 FileInfoSize < sizeof(*FileInfo))
1148 return Version;
1149
1150 const unsigned Major = (FileInfo->dwFileVersionMS >> 16) & 0xFFFF;
1151 const unsigned Minor = (FileInfo->dwFileVersionMS ) & 0xFFFF;
1152 const unsigned Micro = (FileInfo->dwFileVersionLS >> 16) & 0xFFFF;
1153
1154 Version = VersionTuple(Major, Minor, Micro);
1155#endif
1156 return Version;
1157}
1158
Igor Kudrinf2e75242015-09-24 05:16:36 +00001159void MSVCToolChain::AddSystemIncludeWithSubfolder(
1160 const ArgList &DriverArgs, ArgStringList &CC1Args,
1161 const std::string &folder, const Twine &subfolder1, const Twine &subfolder2,
1162 const Twine &subfolder3) const {
Zachary Turner0eaf8fc2014-10-22 20:40:28 +00001163 llvm::SmallString<128> path(folder);
Igor Kudrinf2e75242015-09-24 05:16:36 +00001164 llvm::sys::path::append(path, subfolder1, subfolder2, subfolder3);
Yaron Keren92e1b622015-03-18 10:17:07 +00001165 addSystemInclude(DriverArgs, CC1Args, path);
Zachary Turner0eaf8fc2014-10-22 20:40:28 +00001166}
1167
Saleem Abdulrasool819f3912014-10-22 02:37:29 +00001168void MSVCToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
1169 ArgStringList &CC1Args) const {
Chandler Carruth1fc603e2011-12-17 23:10:01 +00001170 if (DriverArgs.hasArg(options::OPT_nostdinc))
1171 return;
1172
1173 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
Igor Kudrinf2e75242015-09-24 05:16:36 +00001174 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, getDriver().ResourceDir,
1175 "include");
Chandler Carruth1fc603e2011-12-17 23:10:01 +00001176 }
1177
Nico Weberfd3e1ad2016-04-12 19:04:37 +00001178 // Add %INCLUDE%-like directories from the -imsvc flag.
1179 for (const auto &Path : DriverArgs.getAllArgValues(options::OPT__SLASH_imsvc))
1180 addSystemInclude(DriverArgs, CC1Args, Path);
1181
Chandler Carruth1fc603e2011-12-17 23:10:01 +00001182 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
1183 return;
1184
Joao Matos792d7af2012-09-04 17:29:52 +00001185 // Honor %INCLUDE%. It should know essential search paths with vcvarsall.bat.
David Majnemer85c25b42016-07-24 17:44:03 +00001186 if (llvm::Optional<std::string> cl_include_dir =
1187 llvm::sys::Process::GetEnv("INCLUDE")) {
Joao Matos792d7af2012-09-04 17:29:52 +00001188 SmallVector<StringRef, 8> Dirs;
David Majnemer85c25b42016-07-24 17:44:03 +00001189 StringRef(*cl_include_dir)
Reid Kleckner77b45ba2014-04-23 00:15:01 +00001190 .split(Dirs, ";", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
1191 for (StringRef Dir : Dirs)
1192 addSystemInclude(DriverArgs, CC1Args, Dir);
1193 if (!Dirs.empty())
1194 return;
Joao Matos792d7af2012-09-04 17:29:52 +00001195 }
1196
Joao Matos792d7af2012-09-04 17:29:52 +00001197 // When built with access to the proper Windows APIs, try to actually find
1198 // the correct include paths first.
Zachary Turnerf6302522017-03-15 16:07:35 +00001199 if (!VCToolChainPath.empty()) {
1200 addSystemInclude(DriverArgs, CC1Args,
1201 getSubDirectoryPath(SubDirectoryType::Include));
Zachary Turner0eaf8fc2014-10-22 20:40:28 +00001202
Zachary Turnerf6302522017-03-15 16:07:35 +00001203 if (useUniversalCRT()) {
Reid Kleckner7531f7d2015-09-11 00:09:39 +00001204 std::string UniversalCRTSdkPath;
1205 std::string UCRTVersion;
1206 if (getUniversalCRTSdkDir(UniversalCRTSdkPath, UCRTVersion)) {
Igor Kudrinf2e75242015-09-24 05:16:36 +00001207 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, UniversalCRTSdkPath,
1208 "Include", UCRTVersion, "ucrt");
Reid Kleckner7531f7d2015-09-11 00:09:39 +00001209 }
1210 }
1211
Zachary Turner0eaf8fc2014-10-22 20:40:28 +00001212 std::string WindowsSDKDir;
Igor Kudrinf2e75242015-09-24 05:16:36 +00001213 int major;
1214 std::string windowsSDKIncludeVersion;
1215 std::string windowsSDKLibVersion;
1216 if (getWindowsSDKDir(WindowsSDKDir, major, windowsSDKIncludeVersion,
1217 windowsSDKLibVersion)) {
Zachary Turner0eaf8fc2014-10-22 20:40:28 +00001218 if (major >= 8) {
Igor Kudrinf2e75242015-09-24 05:16:36 +00001219 // Note: windowsSDKIncludeVersion is empty for SDKs prior to v10.
1220 // Anyway, llvm::sys::path::append is able to manage it.
Zachary Turner0eaf8fc2014-10-22 20:40:28 +00001221 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
Igor Kudrinf2e75242015-09-24 05:16:36 +00001222 "include", windowsSDKIncludeVersion,
1223 "shared");
Zachary Turner0eaf8fc2014-10-22 20:40:28 +00001224 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
Igor Kudrinf2e75242015-09-24 05:16:36 +00001225 "include", windowsSDKIncludeVersion,
1226 "um");
Zachary Turner0eaf8fc2014-10-22 20:40:28 +00001227 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
Igor Kudrinf2e75242015-09-24 05:16:36 +00001228 "include", windowsSDKIncludeVersion,
1229 "winrt");
Zachary Turner0eaf8fc2014-10-22 20:40:28 +00001230 } else {
1231 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
1232 "include");
1233 }
Reid Kleckner77b45ba2014-04-23 00:15:01 +00001234 }
Zachary Turnerf6302522017-03-15 16:07:35 +00001235
Joao Matos792d7af2012-09-04 17:29:52 +00001236 return;
1237 }
Joao Matos792d7af2012-09-04 17:29:52 +00001238
David Majnemerd5f7d192016-07-25 04:47:44 +00001239#if defined(LLVM_ON_WIN32)
Joao Matos792d7af2012-09-04 17:29:52 +00001240 // As a fallback, select default install paths.
Alp Tokerfcce1832014-06-22 03:27:45 +00001241 // FIXME: Don't guess drives and paths like this on Windows.
Joao Matos792d7af2012-09-04 17:29:52 +00001242 const StringRef Paths[] = {
1243 "C:/Program Files/Microsoft Visual Studio 10.0/VC/include",
1244 "C:/Program Files/Microsoft Visual Studio 9.0/VC/include",
1245 "C:/Program Files/Microsoft Visual Studio 9.0/VC/PlatformSDK/Include",
1246 "C:/Program Files/Microsoft Visual Studio 8/VC/include",
1247 "C:/Program Files/Microsoft Visual Studio 8/VC/PlatformSDK/Include"
1248 };
1249 addSystemIncludes(DriverArgs, CC1Args, Paths);
David Majnemerd5f7d192016-07-25 04:47:44 +00001250#endif
Chandler Carruth1fc603e2011-12-17 23:10:01 +00001251}
1252
Saleem Abdulrasool819f3912014-10-22 02:37:29 +00001253void MSVCToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
1254 ArgStringList &CC1Args) const {
Chandler Carruth1fc603e2011-12-17 23:10:01 +00001255 // FIXME: There should probably be logic here to find libc++ on Windows.
1256}
David Majnemere11d3732015-06-08 00:22:46 +00001257
David L. Jones24fb20c2016-12-07 23:41:58 +00001258VersionTuple MSVCToolChain::computeMSVCVersion(const Driver *D,
1259 const ArgList &Args) const {
1260 bool IsWindowsMSVC = getTriple().isWindowsMSVCEnvironment();
1261 VersionTuple MSVT = ToolChain::computeMSVCVersion(D, Args);
Zachary Turnerf6302522017-03-15 16:07:35 +00001262 if (MSVT.empty())
1263 MSVT = getMSVCVersionFromTriple(getTriple());
1264 if (MSVT.empty() && IsWindowsMSVC)
1265 MSVT = getMSVCVersionFromExe(getSubDirectoryPath(SubDirectoryType::Bin));
David L. Jones24fb20c2016-12-07 23:41:58 +00001266 if (MSVT.empty() &&
1267 Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions,
1268 IsWindowsMSVC)) {
Reid Klecknerc65f16c2017-10-06 21:02:28 +00001269 // -fms-compatibility-version=19.11 is default, aka 2017
1270 MSVT = VersionTuple(19, 11);
David L. Jones24fb20c2016-12-07 23:41:58 +00001271 }
1272 return MSVT;
1273}
1274
David Majnemere11d3732015-06-08 00:22:46 +00001275std::string
1276MSVCToolChain::ComputeEffectiveClangTriple(const ArgList &Args,
1277 types::ID InputType) const {
David L. Jones24fb20c2016-12-07 23:41:58 +00001278 // The MSVC version doesn't care about the architecture, even though it
1279 // may look at the triple internally.
1280 VersionTuple MSVT = computeMSVCVersion(/*D=*/nullptr, Args);
David Majnemere11d3732015-06-08 00:22:46 +00001281 MSVT = VersionTuple(MSVT.getMajor(), MSVT.getMinor().getValueOr(0),
1282 MSVT.getSubminor().getValueOr(0));
1283
David L. Jones24fb20c2016-12-07 23:41:58 +00001284 // For the rest of the triple, however, a computed architecture name may
1285 // be needed.
1286 llvm::Triple Triple(ToolChain::ComputeEffectiveClangTriple(Args, InputType));
David Majnemer75fdd6b2015-06-09 06:30:01 +00001287 if (Triple.getEnvironment() == llvm::Triple::MSVC) {
1288 StringRef ObjFmt = Triple.getEnvironmentName().split('-').second;
1289 if (ObjFmt.empty())
1290 Triple.setEnvironmentName((Twine("msvc") + MSVT.getAsString()).str());
1291 else
1292 Triple.setEnvironmentName(
1293 (Twine("msvc") + MSVT.getAsString() + Twine('-') + ObjFmt).str());
1294 }
David Majnemere11d3732015-06-08 00:22:46 +00001295 return Triple.getTriple();
1296}
Alexey Samsonov7f2a0d22015-06-19 21:36:47 +00001297
1298SanitizerMask MSVCToolChain::getSupportedSanitizers() const {
1299 SanitizerMask Res = ToolChain::getSupportedSanitizers();
1300 Res |= SanitizerKind::Address;
Alexey Samsonov7f2a0d22015-06-19 21:36:47 +00001301 return Res;
1302}
David Majnemer015ce0f2015-07-27 07:32:11 +00001303
Hans Wennborg21d73d22016-01-12 23:17:03 +00001304static void TranslateOptArg(Arg *A, llvm::opt::DerivedArgList &DAL,
1305 bool SupportsForcingFramePointer,
1306 const char *ExpandChar, const OptTable &Opts) {
1307 assert(A->getOption().matches(options::OPT__SLASH_O));
1308
1309 StringRef OptStr = A->getValue();
1310 for (size_t I = 0, E = OptStr.size(); I != E; ++I) {
1311 const char &OptChar = *(OptStr.data() + I);
1312 switch (OptChar) {
1313 default:
1314 break;
1315 case '1':
1316 case '2':
1317 case 'x':
1318 case 'd':
Reid Klecknerf6d65df2017-10-03 00:14:03 +00001319 // Ignore /O[12xd] flags that aren't the last one on the command line.
1320 // Only the last one gets expanded.
1321 if (&OptChar != ExpandChar) {
1322 A->claim();
1323 break;
1324 }
1325 if (OptChar == 'd') {
1326 DAL.AddFlagArg(A, Opts.getOption(options::OPT_O0));
1327 } else {
1328 if (OptChar == '1') {
1329 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "s");
1330 } else if (OptChar == '2' || OptChar == 'x') {
1331 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
1332 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "2");
Hans Wennborg21d73d22016-01-12 23:17:03 +00001333 }
Reid Klecknerf6d65df2017-10-03 00:14:03 +00001334 if (SupportsForcingFramePointer &&
1335 !DAL.hasArgNoClaim(options::OPT_fno_omit_frame_pointer))
1336 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fomit_frame_pointer));
1337 if (OptChar == '1' || OptChar == '2')
1338 DAL.AddFlagArg(A, Opts.getOption(options::OPT_ffunction_sections));
Hans Wennborg21d73d22016-01-12 23:17:03 +00001339 }
1340 break;
1341 case 'b':
Hans Wennborg3270bdb2016-05-24 21:23:29 +00001342 if (I + 1 != E && isdigit(OptStr[I + 1])) {
1343 switch (OptStr[I + 1]) {
1344 case '0':
1345 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_inline));
1346 break;
1347 case '1':
Hans Wennborg44d061a2016-06-22 16:56:16 +00001348 DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_hint_functions));
Hans Wennborg3270bdb2016-05-24 21:23:29 +00001349 break;
1350 case '2':
1351 DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_functions));
1352 break;
1353 }
Hans Wennborg21d73d22016-01-12 23:17:03 +00001354 ++I;
Hans Wennborg3270bdb2016-05-24 21:23:29 +00001355 }
Hans Wennborg21d73d22016-01-12 23:17:03 +00001356 break;
1357 case 'g':
1358 break;
1359 case 'i':
1360 if (I + 1 != E && OptStr[I + 1] == '-') {
1361 ++I;
1362 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_builtin));
1363 } else {
1364 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
1365 }
1366 break;
1367 case 's':
1368 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "s");
1369 break;
1370 case 't':
1371 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "2");
1372 break;
1373 case 'y': {
1374 bool OmitFramePointer = true;
1375 if (I + 1 != E && OptStr[I + 1] == '-') {
1376 OmitFramePointer = false;
1377 ++I;
1378 }
1379 if (SupportsForcingFramePointer) {
1380 if (OmitFramePointer)
1381 DAL.AddFlagArg(A,
1382 Opts.getOption(options::OPT_fomit_frame_pointer));
1383 else
1384 DAL.AddFlagArg(
1385 A, Opts.getOption(options::OPT_fno_omit_frame_pointer));
Nico Weber9c3fca32016-03-23 15:37:41 +00001386 } else {
1387 // Don't warn about /Oy- in 64-bit builds (where
1388 // SupportsForcingFramePointer is false). The flag having no effect
1389 // there is a compiler-internal optimization, and people shouldn't have
1390 // to special-case their build files for 64-bit clang-cl.
1391 A->claim();
Hans Wennborg21d73d22016-01-12 23:17:03 +00001392 }
1393 break;
1394 }
1395 }
1396 }
1397}
1398
1399static void TranslateDArg(Arg *A, llvm::opt::DerivedArgList &DAL,
1400 const OptTable &Opts) {
1401 assert(A->getOption().matches(options::OPT_D));
1402
1403 StringRef Val = A->getValue();
1404 size_t Hash = Val.find('#');
1405 if (Hash == StringRef::npos || Hash > Val.find('=')) {
1406 DAL.append(A);
1407 return;
1408 }
1409
1410 std::string NewVal = Val;
1411 NewVal[Hash] = '=';
1412 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_D), NewVal);
1413}
1414
David Majnemer015ce0f2015-07-27 07:32:11 +00001415llvm::opt::DerivedArgList *
1416MSVCToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args,
Samuel Antao31fef982016-10-27 17:39:44 +00001417 StringRef BoundArch, Action::OffloadKind) const {
David Majnemer015ce0f2015-07-27 07:32:11 +00001418 DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
1419 const OptTable &Opts = getDriver().getOpts();
1420
David Majnemer7ab76f22015-08-25 00:46:45 +00001421 // /Oy and /Oy- only has an effect under X86-32.
1422 bool SupportsForcingFramePointer = getArch() == llvm::Triple::x86;
1423
David Majnemer015ce0f2015-07-27 07:32:11 +00001424 // The -O[12xd] flag actually expands to several flags. We must desugar the
1425 // flags so that options embedded can be negated. For example, the '-O2' flag
1426 // enables '-Oy'. Expanding '-O2' into its constituent flags allows us to
1427 // correctly handle '-O2 -Oy-' where the trailing '-Oy-' disables a single
1428 // aspect of '-O2'.
1429 //
1430 // Note that this expansion logic only applies to the *last* of '[12xd]'.
1431
1432 // First step is to search for the character we'd like to expand.
1433 const char *ExpandChar = nullptr;
Reid Klecknerf6d65df2017-10-03 00:14:03 +00001434 for (Arg *A : Args.filtered(options::OPT__SLASH_O)) {
David Majnemer015ce0f2015-07-27 07:32:11 +00001435 StringRef OptStr = A->getValue();
1436 for (size_t I = 0, E = OptStr.size(); I != E; ++I) {
Hans Wennborgdebfed92016-05-25 00:43:45 +00001437 char OptChar = OptStr[I];
1438 char PrevChar = I > 0 ? OptStr[I - 1] : '0';
1439 if (PrevChar == 'b') {
1440 // OptChar does not expand; it's an argument to the previous char.
1441 continue;
1442 }
David Majnemer015ce0f2015-07-27 07:32:11 +00001443 if (OptChar == '1' || OptChar == '2' || OptChar == 'x' || OptChar == 'd')
1444 ExpandChar = OptStr.data() + I;
1445 }
1446 }
1447
David Majnemer015ce0f2015-07-27 07:32:11 +00001448 for (Arg *A : Args) {
Hans Wennborg21d73d22016-01-12 23:17:03 +00001449 if (A->getOption().matches(options::OPT__SLASH_O)) {
1450 // The -O flag actually takes an amalgam of other options. For example,
1451 // '/Ogyb2' is equivalent to '/Og' '/Oy' '/Ob2'.
1452 TranslateOptArg(A, *DAL, SupportsForcingFramePointer, ExpandChar, Opts);
1453 } else if (A->getOption().matches(options::OPT_D)) {
1454 // Translate -Dfoo#bar into -Dfoo=bar.
1455 TranslateDArg(A, *DAL, Opts);
1456 } else {
David Majnemer015ce0f2015-07-27 07:32:11 +00001457 DAL->append(A);
David Majnemer015ce0f2015-07-27 07:32:11 +00001458 }
1459 }
Hans Wennborg21d73d22016-01-12 23:17:03 +00001460
David Majnemer015ce0f2015-07-27 07:32:11 +00001461 return DAL;
1462}