blob: 3d7c1d76ae76ea0c9272c3cec9f6791945fce202 [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,
79 bool &IsVS2017OrNewer) {
80 // These variables are typically set by vcvarsall.bat
81 // when launching a developer command prompt.
82 if (llvm::Optional<std::string> VCToolsInstallDir =
83 llvm::sys::Process::GetEnv("VCToolsInstallDir")) {
84 // This is only set by newer Visual Studios, and it leads straight to
85 // the toolchain directory.
86 Path = std::move(*VCToolsInstallDir);
87 IsVS2017OrNewer = true;
88 return true;
89 }
90 if (llvm::Optional<std::string> VCInstallDir =
91 llvm::sys::Process::GetEnv("VCINSTALLDIR")) {
92 // If the previous variable isn't set but this one is, then we've found
93 // an older Visual Studio. This variable is set by newer Visual Studios too,
94 // so this check has to appear second.
95 // In older Visual Studios, the VC directory is the toolchain.
96 Path = std::move(*VCInstallDir);
97 IsVS2017OrNewer = false;
98 return true;
99 }
100
101 // We couldn't find any VC environment variables. Let's walk through PATH and
102 // see if it leads us to a VC toolchain bin directory. If it does, pick the
103 // first one that we find.
104 if (llvm::Optional<std::string> PathEnv =
105 llvm::sys::Process::GetEnv("PATH")) {
106 llvm::SmallVector<llvm::StringRef, 8> PathEntries;
107 llvm::StringRef(*PathEnv).split(PathEntries, llvm::sys::EnvPathSeparator);
108 for (llvm::StringRef PathEntry : PathEntries) {
109 if (PathEntry.empty())
110 continue;
111
112 llvm::SmallString<256> ExeTestPath;
113
114 // If cl.exe doesn't exist, then this definitely isn't a VC toolchain.
115 ExeTestPath = PathEntry;
116 llvm::sys::path::append(ExeTestPath, "cl.exe");
117 if (!llvm::sys::fs::exists(ExeTestPath))
118 continue;
119
120 // cl.exe existing isn't a conclusive test for a VC toolchain; clang also
121 // has a cl.exe. So let's check for link.exe too.
122 ExeTestPath = PathEntry;
123 llvm::sys::path::append(ExeTestPath, "link.exe");
124 if (!llvm::sys::fs::exists(ExeTestPath))
125 continue;
126
127 // whatever/VC/bin --> old toolchain, VC dir is toolchain dir.
128 if (llvm::sys::path::filename(PathEntry) == "bin") {
129 llvm::StringRef ParentPath = llvm::sys::path::parent_path(PathEntry);
130 if (llvm::sys::path::filename(ParentPath) == "VC") {
131 Path = ParentPath;
132 IsVS2017OrNewer = false;
133 return true;
134 }
135
136 } else {
137 // This could be a new (>=VS2017) toolchain. If it is, we should find
138 // path components with these prefixes when walking backwards through
139 // the path.
140 // Note: empty strings match anything.
141 llvm::StringRef ExpectedPrefixes[] = {"", "Host", "bin", "",
142 "MSVC", "Tools", "VC"};
143
144 auto It = llvm::sys::path::rbegin(PathEntry);
145 auto End = llvm::sys::path::rend(PathEntry);
146 for (llvm::StringRef Prefix : ExpectedPrefixes) {
147 if (It == End)
148 goto NotAToolChain;
149 if (!It->startswith(Prefix))
150 goto NotAToolChain;
151 ++It;
152 }
153
154 // We've found a new toolchain!
155 // Back up 3 times (/bin/Host/arch) to get the root path.
156 llvm::StringRef ToolChainPath(PathEntry);
157 for (int i = 0; i < 3; ++i)
158 ToolChainPath = llvm::sys::path::parent_path(ToolChainPath);
159
160 Path = ToolChainPath;
161 IsVS2017OrNewer = true;
162 return true;
163 }
164
165 NotAToolChain:
166 continue;
167 }
168 }
169 return false;
170}
171
172// Query the Setup Config server for installs, then pick the newest version
173// and find its default VC toolchain.
174// This is the preferred way to discover new Visual Studios, as they're no
175// longer listed in the registry.
176static bool findVCToolChainViaSetupConfig(std::string &Path,
177 bool &IsVS2017OrNewer) {
Zachary Turner545202b2017-03-15 17:09:36 +0000178#if !defined(USE_MSVC_SETUP_API)
Zachary Turnerf6302522017-03-15 16:07:35 +0000179 return false;
180#else
181 // FIXME: This really should be done once in the top-level program's main
182 // function, as it may have already been initialized with a different
183 // threading model otherwise.
184 llvm::sys::InitializeCOMRAII COM(llvm::sys::COMThreadingMode::SingleThreaded);
185 HRESULT HR;
186
187 // _com_ptr_t will throw a _com_error if a COM calls fail.
188 // The LLVM coding standards forbid exception handling, so we'll have to
189 // stop them from being thrown in the first place.
190 // The destructor will put the regular error handler back when we leave
191 // this scope.
192 struct SuppressCOMErrorsRAII {
193 static void __stdcall handler(HRESULT hr, IErrorInfo *perrinfo) {}
194
195 SuppressCOMErrorsRAII() { _set_com_error_handler(handler); }
196
197 ~SuppressCOMErrorsRAII() { _set_com_error_handler(_com_raise_error); }
198
199 } COMErrorSuppressor;
200
201 ISetupConfigurationPtr Query;
202 HR = Query.CreateInstance(__uuidof(SetupConfiguration));
203 if (FAILED(HR))
204 return false;
205
206 IEnumSetupInstancesPtr EnumInstances;
207 HR = ISetupConfiguration2Ptr(Query)->EnumAllInstances(&EnumInstances);
208 if (FAILED(HR))
209 return false;
210
211 ISetupInstancePtr Instance;
212 HR = EnumInstances->Next(1, &Instance, nullptr);
213 if (HR != S_OK)
214 return false;
215
216 ISetupInstancePtr NewestInstance;
217 Optional<uint64_t> NewestVersionNum;
218 do {
219 bstr_t VersionString;
220 uint64_t VersionNum;
221 HR = Instance->GetInstallationVersion(VersionString.GetAddress());
222 if (FAILED(HR))
223 continue;
224 HR = ISetupHelperPtr(Query)->ParseVersion(VersionString, &VersionNum);
225 if (FAILED(HR))
226 continue;
227 if (!NewestVersionNum || (VersionNum > NewestVersionNum)) {
228 NewestInstance = Instance;
229 NewestVersionNum = VersionNum;
230 }
231 } while ((HR = EnumInstances->Next(1, &Instance, nullptr)) == S_OK);
232
233 if (!NewestInstance)
234 return false;
235
236 bstr_t VCPathWide;
237 HR = NewestInstance->ResolvePath(L"VC", VCPathWide.GetAddress());
238 if (FAILED(HR))
239 return false;
240
241 std::string VCRootPath;
242 llvm::convertWideToUTF8(std::wstring(VCPathWide), VCRootPath);
243
244 llvm::SmallString<256> ToolsVersionFilePath(VCRootPath);
245 llvm::sys::path::append(ToolsVersionFilePath, "Auxiliary", "Build",
246 "Microsoft.VCToolsVersion.default.txt");
247
248 auto ToolsVersionFile = llvm::MemoryBuffer::getFile(ToolsVersionFilePath);
249 if (!ToolsVersionFile)
250 return false;
251
252 llvm::SmallString<256> ToolchainPath(VCRootPath);
253 llvm::sys::path::append(ToolchainPath, "Tools", "MSVC",
254 ToolsVersionFile->get()->getBuffer().rtrim());
255 if (!llvm::sys::fs::is_directory(ToolchainPath))
256 return false;
257
258 Path = ToolchainPath.str();
259 IsVS2017OrNewer = true;
260 return true;
261#endif
262}
263
264// Look in the registry for Visual Studio installs, and use that to get
265// a toolchain path. VS2017 and newer don't get added to the registry.
266// So if we find something here, we know that it's an older version.
267static bool findVCToolChainViaRegistry(std::string &Path,
268 bool &IsVS2017OrNewer) {
269 std::string VSInstallPath;
270 if (getSystemRegistryString(R"(SOFTWARE\Microsoft\VisualStudio\$VERSION)",
271 "InstallDir", VSInstallPath, nullptr) ||
272 getSystemRegistryString(R"(SOFTWARE\Microsoft\VCExpress\$VERSION)",
273 "InstallDir", VSInstallPath, nullptr)) {
274 if (!VSInstallPath.empty()) {
275 llvm::SmallString<256> VCPath(llvm::StringRef(
276 VSInstallPath.c_str(), VSInstallPath.find(R"(\Common7\IDE)")));
277 llvm::sys::path::append(VCPath, "VC");
278
279 Path = VCPath.str();
280 IsVS2017OrNewer = false;
281 return true;
282 }
283 }
284 return false;
285}
286
David L. Jonesf561aba2017-03-08 01:02:16 +0000287// Try to find Exe from a Visual Studio distribution. This first tries to find
288// an installed copy of Visual Studio and, failing that, looks in the PATH,
289// making sure that whatever executable that's found is not a same-named exe
290// from clang itself to prevent clang from falling back to itself.
291static std::string FindVisualStudioExecutable(const ToolChain &TC,
Zachary Turnerf6302522017-03-15 16:07:35 +0000292 const char *Exe) {
David L. Jonesf561aba2017-03-08 01:02:16 +0000293 const auto &MSVC = static_cast<const toolchains::MSVCToolChain &>(TC);
Zachary Turnerf6302522017-03-15 16:07:35 +0000294 SmallString<128> FilePath(MSVC.getSubDirectoryPath(
295 toolchains::MSVCToolChain::SubDirectoryType::Bin));
296 llvm::sys::path::append(FilePath, Exe);
297 return llvm::sys::fs::can_execute(FilePath) ? FilePath.str() : Exe;
David L. Jonesf561aba2017-03-08 01:02:16 +0000298}
299
300void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA,
301 const InputInfo &Output,
302 const InputInfoList &Inputs,
303 const ArgList &Args,
304 const char *LinkingOutput) const {
305 ArgStringList CmdArgs;
Zachary Turnerf6302522017-03-15 16:07:35 +0000306
307 auto &TC = static_cast<const toolchains::MSVCToolChain &>(getToolChain());
David L. Jonesf561aba2017-03-08 01:02:16 +0000308
309 assert((Output.isFilename() || Output.isNothing()) && "invalid output");
310 if (Output.isFilename())
311 CmdArgs.push_back(
312 Args.MakeArgString(std::string("-out:") + Output.getFilename()));
313
314 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles) &&
315 !C.getDriver().IsCLMode())
316 CmdArgs.push_back("-defaultlib:libcmt");
317
318 if (!llvm::sys::Process::GetEnv("LIB")) {
319 // If the VC environment hasn't been configured (perhaps because the user
320 // did not run vcvarsall), try to build a consistent link environment. If
321 // the environment variable is set however, assume the user knows what
322 // they're doing.
Zachary Turnerf6302522017-03-15 16:07:35 +0000323 CmdArgs.push_back(Args.MakeArgString(
324 Twine("-libpath:") +
325 TC.getSubDirectoryPath(
326 toolchains::MSVCToolChain::SubDirectoryType::Lib)));
David L. Jonesf561aba2017-03-08 01:02:16 +0000327
Zachary Turnerf6302522017-03-15 16:07:35 +0000328 if (TC.useUniversalCRT()) {
329 std::string UniversalCRTLibPath;
330 if (TC.getUniversalCRTLibraryPath(UniversalCRTLibPath))
331 CmdArgs.push_back(
332 Args.MakeArgString(Twine("-libpath:") + UniversalCRTLibPath));
David L. Jonesf561aba2017-03-08 01:02:16 +0000333 }
334
335 std::string WindowsSdkLibPath;
Zachary Turnerf6302522017-03-15 16:07:35 +0000336 if (TC.getWindowsSDKLibraryPath(WindowsSdkLibPath))
David L. Jonesf561aba2017-03-08 01:02:16 +0000337 CmdArgs.push_back(
338 Args.MakeArgString(std::string("-libpath:") + WindowsSdkLibPath));
339 }
340
341 if (!C.getDriver().IsCLMode() && Args.hasArg(options::OPT_L))
342 for (const auto &LibPath : Args.getAllArgValues(options::OPT_L))
343 CmdArgs.push_back(Args.MakeArgString("-libpath:" + LibPath));
344
345 CmdArgs.push_back("-nologo");
346
347 if (Args.hasArg(options::OPT_g_Group, options::OPT__SLASH_Z7,
348 options::OPT__SLASH_Zd))
349 CmdArgs.push_back("-debug");
350
351 bool DLL = Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd,
352 options::OPT_shared);
353 if (DLL) {
354 CmdArgs.push_back(Args.MakeArgString("-dll"));
355
356 SmallString<128> ImplibName(Output.getFilename());
357 llvm::sys::path::replace_extension(ImplibName, "lib");
358 CmdArgs.push_back(Args.MakeArgString(std::string("-implib:") + ImplibName));
359 }
360
361 if (TC.getSanitizerArgs().needsAsanRt()) {
362 CmdArgs.push_back(Args.MakeArgString("-debug"));
363 CmdArgs.push_back(Args.MakeArgString("-incremental:no"));
364 if (TC.getSanitizerArgs().needsSharedAsanRt() ||
365 Args.hasArg(options::OPT__SLASH_MD, options::OPT__SLASH_MDd)) {
366 for (const auto &Lib : {"asan_dynamic", "asan_dynamic_runtime_thunk"})
367 CmdArgs.push_back(TC.getCompilerRTArgString(Args, Lib));
368 // Make sure the dynamic runtime thunk is not optimized out at link time
369 // to ensure proper SEH handling.
370 CmdArgs.push_back(Args.MakeArgString(
371 TC.getArch() == llvm::Triple::x86
372 ? "-include:___asan_seh_interceptor"
373 : "-include:__asan_seh_interceptor"));
374 // Make sure the linker consider all object files from the dynamic runtime
375 // thunk.
376 CmdArgs.push_back(Args.MakeArgString(std::string("-wholearchive:") +
377 TC.getCompilerRT(Args, "asan_dynamic_runtime_thunk")));
378 } else if (DLL) {
379 CmdArgs.push_back(TC.getCompilerRTArgString(Args, "asan_dll_thunk"));
380 } else {
381 for (const auto &Lib : {"asan", "asan_cxx"}) {
382 CmdArgs.push_back(TC.getCompilerRTArgString(Args, Lib));
383 // Make sure the linker consider all object files from the static lib.
384 // This is necessary because instrumented dlls need access to all the
385 // interface exported by the static lib in the main executable.
386 CmdArgs.push_back(Args.MakeArgString(std::string("-wholearchive:") +
387 TC.getCompilerRT(Args, Lib)));
388 }
389 }
390 }
391
392 Args.AddAllArgValues(CmdArgs, options::OPT__SLASH_link);
393
394 if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
395 options::OPT_fno_openmp, false)) {
396 CmdArgs.push_back("-nodefaultlib:vcomp.lib");
397 CmdArgs.push_back("-nodefaultlib:vcompd.lib");
398 CmdArgs.push_back(Args.MakeArgString(std::string("-libpath:") +
399 TC.getDriver().Dir + "/../lib"));
400 switch (TC.getDriver().getOpenMPRuntime(Args)) {
401 case Driver::OMPRT_OMP:
402 CmdArgs.push_back("-defaultlib:libomp.lib");
403 break;
404 case Driver::OMPRT_IOMP5:
405 CmdArgs.push_back("-defaultlib:libiomp5md.lib");
406 break;
407 case Driver::OMPRT_GOMP:
408 break;
409 case Driver::OMPRT_Unknown:
410 // Already diagnosed.
411 break;
412 }
413 }
414
415 // Add compiler-rt lib in case if it was explicitly
416 // specified as an argument for --rtlib option.
417 if (!Args.hasArg(options::OPT_nostdlib)) {
418 AddRunTimeLibs(TC, TC.getDriver(), CmdArgs, Args);
419 }
420
421 // Add filenames, libraries, and other linker inputs.
422 for (const auto &Input : Inputs) {
423 if (Input.isFilename()) {
424 CmdArgs.push_back(Input.getFilename());
425 continue;
426 }
427
428 const Arg &A = Input.getInputArg();
429
430 // Render -l options differently for the MSVC linker.
431 if (A.getOption().matches(options::OPT_l)) {
432 StringRef Lib = A.getValue();
433 const char *LinkLibArg;
434 if (Lib.endswith(".lib"))
435 LinkLibArg = Args.MakeArgString(Lib);
436 else
437 LinkLibArg = Args.MakeArgString(Lib + ".lib");
438 CmdArgs.push_back(LinkLibArg);
439 continue;
440 }
441
442 // Otherwise, this is some other kind of linker input option like -Wl, -z,
443 // or -L. Render it, even if MSVC doesn't understand it.
444 A.renderAsInput(Args, CmdArgs);
445 }
446
447 TC.addProfileRTLibs(Args, CmdArgs);
448
449 // We need to special case some linker paths. In the case of lld, we need to
450 // translate 'lld' into 'lld-link', and in the case of the regular msvc
451 // linker, we need to use a special search algorithm.
452 llvm::SmallString<128> linkPath;
453 StringRef Linker = Args.getLastArgValue(options::OPT_fuse_ld_EQ, "link");
454 if (Linker.equals_lower("lld"))
455 Linker = "lld-link";
456
457 if (Linker.equals_lower("link")) {
458 // If we're using the MSVC linker, it's not sufficient to just use link
459 // from the program PATH, because other environments like GnuWin32 install
460 // their own link.exe which may come first.
Zachary Turnerf6302522017-03-15 16:07:35 +0000461 linkPath = FindVisualStudioExecutable(TC, "link.exe");
David L. Jonesf561aba2017-03-08 01:02:16 +0000462 } else {
463 linkPath = Linker;
464 llvm::sys::path::replace_extension(linkPath, "exe");
465 linkPath = TC.GetProgramPath(linkPath.c_str());
466 }
467
468 const char *Exec = Args.MakeArgString(linkPath);
469 C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
470}
471
472void visualstudio::Compiler::ConstructJob(Compilation &C, const JobAction &JA,
473 const InputInfo &Output,
474 const InputInfoList &Inputs,
475 const ArgList &Args,
476 const char *LinkingOutput) const {
477 C.addCommand(GetCommand(C, JA, Output, Inputs, Args, LinkingOutput));
478}
479
480std::unique_ptr<Command> visualstudio::Compiler::GetCommand(
481 Compilation &C, const JobAction &JA, const InputInfo &Output,
482 const InputInfoList &Inputs, const ArgList &Args,
483 const char *LinkingOutput) const {
484 ArgStringList CmdArgs;
485 CmdArgs.push_back("/nologo");
486 CmdArgs.push_back("/c"); // Compile only.
487 CmdArgs.push_back("/W0"); // No warnings.
488
489 // The goal is to be able to invoke this tool correctly based on
490 // any flag accepted by clang-cl.
491
492 // These are spelled the same way in clang and cl.exe,.
493 Args.AddAllArgs(CmdArgs, {options::OPT_D, options::OPT_U, options::OPT_I});
494
495 // Optimization level.
496 if (Arg *A = Args.getLastArg(options::OPT_fbuiltin, options::OPT_fno_builtin))
497 CmdArgs.push_back(A->getOption().getID() == options::OPT_fbuiltin ? "/Oi"
498 : "/Oi-");
499 if (Arg *A = Args.getLastArg(options::OPT_O, options::OPT_O0)) {
500 if (A->getOption().getID() == options::OPT_O0) {
501 CmdArgs.push_back("/Od");
502 } else {
503 CmdArgs.push_back("/Og");
504
505 StringRef OptLevel = A->getValue();
506 if (OptLevel == "s" || OptLevel == "z")
507 CmdArgs.push_back("/Os");
508 else
509 CmdArgs.push_back("/Ot");
510
511 CmdArgs.push_back("/Ob2");
512 }
513 }
514 if (Arg *A = Args.getLastArg(options::OPT_fomit_frame_pointer,
515 options::OPT_fno_omit_frame_pointer))
516 CmdArgs.push_back(A->getOption().getID() == options::OPT_fomit_frame_pointer
517 ? "/Oy"
518 : "/Oy-");
519 if (!Args.hasArg(options::OPT_fwritable_strings))
520 CmdArgs.push_back("/GF");
521
522 // Flags for which clang-cl has an alias.
523 // FIXME: How can we ensure this stays in sync with relevant clang-cl options?
524
525 if (Args.hasFlag(options::OPT__SLASH_GR_, options::OPT__SLASH_GR,
526 /*default=*/false))
527 CmdArgs.push_back("/GR-");
528
529 if (Args.hasFlag(options::OPT__SLASH_GS_, options::OPT__SLASH_GS,
530 /*default=*/false))
531 CmdArgs.push_back("/GS-");
532
533 if (Arg *A = Args.getLastArg(options::OPT_ffunction_sections,
534 options::OPT_fno_function_sections))
535 CmdArgs.push_back(A->getOption().getID() == options::OPT_ffunction_sections
536 ? "/Gy"
537 : "/Gy-");
538 if (Arg *A = Args.getLastArg(options::OPT_fdata_sections,
539 options::OPT_fno_data_sections))
540 CmdArgs.push_back(
541 A->getOption().getID() == options::OPT_fdata_sections ? "/Gw" : "/Gw-");
542 if (Args.hasArg(options::OPT_fsyntax_only))
543 CmdArgs.push_back("/Zs");
544 if (Args.hasArg(options::OPT_g_Flag, options::OPT_gline_tables_only,
545 options::OPT__SLASH_Z7))
546 CmdArgs.push_back("/Z7");
547
548 std::vector<std::string> Includes =
549 Args.getAllArgValues(options::OPT_include);
550 for (const auto &Include : Includes)
551 CmdArgs.push_back(Args.MakeArgString(std::string("/FI") + Include));
552
553 // Flags that can simply be passed through.
554 Args.AddAllArgs(CmdArgs, options::OPT__SLASH_LD);
555 Args.AddAllArgs(CmdArgs, options::OPT__SLASH_LDd);
556 Args.AddAllArgs(CmdArgs, options::OPT__SLASH_GX);
557 Args.AddAllArgs(CmdArgs, options::OPT__SLASH_GX_);
558 Args.AddAllArgs(CmdArgs, options::OPT__SLASH_EH);
559 Args.AddAllArgs(CmdArgs, options::OPT__SLASH_Zl);
560
561 // The order of these flags is relevant, so pick the last one.
562 if (Arg *A = Args.getLastArg(options::OPT__SLASH_MD, options::OPT__SLASH_MDd,
563 options::OPT__SLASH_MT, options::OPT__SLASH_MTd))
564 A->render(Args, CmdArgs);
565
566 // Use MSVC's default threadsafe statics behaviour unless there was a flag.
567 if (Arg *A = Args.getLastArg(options::OPT_fthreadsafe_statics,
568 options::OPT_fno_threadsafe_statics)) {
569 CmdArgs.push_back(A->getOption().getID() == options::OPT_fthreadsafe_statics
570 ? "/Zc:threadSafeInit"
571 : "/Zc:threadSafeInit-");
572 }
573
574 // Pass through all unknown arguments so that the fallback command can see
575 // them too.
576 Args.AddAllArgs(CmdArgs, options::OPT_UNKNOWN);
577
578 // Input filename.
579 assert(Inputs.size() == 1);
580 const InputInfo &II = Inputs[0];
581 assert(II.getType() == types::TY_C || II.getType() == types::TY_CXX);
582 CmdArgs.push_back(II.getType() == types::TY_C ? "/Tc" : "/Tp");
583 if (II.isFilename())
584 CmdArgs.push_back(II.getFilename());
585 else
586 II.getInputArg().renderAsInput(Args, CmdArgs);
587
588 // Output filename.
589 assert(Output.getType() == types::TY_Object);
590 const char *Fo =
591 Args.MakeArgString(std::string("/Fo") + Output.getFilename());
592 CmdArgs.push_back(Fo);
593
Zachary Turnerf6302522017-03-15 16:07:35 +0000594 std::string Exec = FindVisualStudioExecutable(getToolChain(), "cl.exe");
David L. Jonesf561aba2017-03-08 01:02:16 +0000595 return llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Exec),
596 CmdArgs, Inputs);
597}
598
Reid Klecknerbf183552017-02-02 19:36:22 +0000599MSVCToolChain::MSVCToolChain(const Driver &D, const llvm::Triple &Triple,
Saleem Abdulrasool819f3912014-10-22 02:37:29 +0000600 const ArgList &Args)
Justin Lebar58891902017-01-05 16:52:29 +0000601 : ToolChain(D, Triple, Args), CudaInstallation(D, Triple, Args) {
Zachary Turner719f58c2014-12-01 23:06:47 +0000602 getProgramPaths().push_back(getDriver().getInstalledDir());
603 if (getDriver().getInstalledDir() != getDriver().Dir)
604 getProgramPaths().push_back(getDriver().Dir);
Zachary Turnerf6302522017-03-15 16:07:35 +0000605
606 // Check the environment first, since that's probably the user telling us
607 // what they want to use.
608 // Failing that, just try to find the newest Visual Studio version we can
609 // and use its default VC toolchain.
610 findVCToolChainViaEnvironment(VCToolChainPath, IsVS2017OrNewer) ||
611 findVCToolChainViaSetupConfig(VCToolChainPath, IsVS2017OrNewer) ||
612 findVCToolChainViaRegistry(VCToolChainPath, IsVS2017OrNewer);
Hans Wennborg1cc6cce2013-08-30 09:42:06 +0000613}
614
Saleem Abdulrasool819f3912014-10-22 02:37:29 +0000615Tool *MSVCToolChain::buildLinker() const {
Zachary Turnerf6302522017-03-15 16:07:35 +0000616 if (VCToolChainPath.empty())
617 getDriver().Diag(clang::diag::warn_drv_msvc_not_found);
Douglas Katzman95354292015-06-23 20:42:09 +0000618 return new tools::visualstudio::Linker(*this);
Hans Wennborg1cc6cce2013-08-30 09:42:06 +0000619}
620
Saleem Abdulrasool819f3912014-10-22 02:37:29 +0000621Tool *MSVCToolChain::buildAssembler() const {
Saleem Abdulrasool377066a2014-03-27 22:50:18 +0000622 if (getTriple().isOSBinFormatMachO())
Douglas Katzman95354292015-06-23 20:42:09 +0000623 return new tools::darwin::Assembler(*this);
Alp Tokerc8d4f0f2013-11-22 08:27:46 +0000624 getDriver().Diag(clang::diag::err_no_external_assembler);
Craig Topper92fc2df2014-05-17 16:56:41 +0000625 return nullptr;
Hans Wennborg1cc6cce2013-08-30 09:42:06 +0000626}
627
Saleem Abdulrasool819f3912014-10-22 02:37:29 +0000628bool MSVCToolChain::IsIntegratedAssemblerDefault() const {
Hans Wennborg1cc6cce2013-08-30 09:42:06 +0000629 return true;
630}
631
Saleem Abdulrasool819f3912014-10-22 02:37:29 +0000632bool MSVCToolChain::IsUnwindTablesDefault() const {
Reid Kleckner6b3a9402014-09-04 18:13:12 +0000633 // Emit unwind tables by default on Win64. All non-x86_32 Windows platforms
634 // such as ARM and PPC actually require unwind tables, but LLVM doesn't know
635 // how to generate them yet.
Akira Hatanakae4218132016-05-05 01:41:07 +0000636
637 // Don't emit unwind tables by default for MachO targets.
638 if (getTriple().isOSBinFormatMachO())
639 return false;
640
Reid Kleckner6b3a9402014-09-04 18:13:12 +0000641 return getArch() == llvm::Triple::x86_64;
Hans Wennborg1cc6cce2013-08-30 09:42:06 +0000642}
643
Reid Kleckner8c190832016-12-28 17:41:36 +0000644bool MSVCToolChain::isPICDefault() const {
645 return getArch() == llvm::Triple::x86_64;
646}
647
648bool MSVCToolChain::isPIEDefault() const {
649 return false;
650}
651
652bool MSVCToolChain::isPICDefaultForced() const {
653 return getArch() == llvm::Triple::x86_64;
654}
655
Justin Lebar58891902017-01-05 16:52:29 +0000656void MSVCToolChain::AddCudaIncludeArgs(const ArgList &DriverArgs,
657 ArgStringList &CC1Args) const {
658 CudaInstallation.AddCudaIncludeArgs(DriverArgs, CC1Args);
659}
660
661void MSVCToolChain::printVerboseInfo(raw_ostream &OS) const {
662 CudaInstallation.print(OS);
663}
664
Zachary Turnerf6302522017-03-15 16:07:35 +0000665// Windows SDKs and VC Toolchains group their contents into subdirectories based
666// on the target architecture. This function converts an llvm::Triple::ArchType
667// to the corresponding subdirectory name.
668static const char *llvmArchToWindowsSDKArch(llvm::Triple::ArchType Arch) {
669 using ArchType = llvm::Triple::ArchType;
670 switch (Arch) {
671 case ArchType::x86:
672 return "x86";
673 case ArchType::x86_64:
674 return "x64";
675 case ArchType::arm:
676 return "arm";
677 default:
678 return "";
679 }
680}
681
682// Similar to the above function, but for Visual Studios before VS2017.
683static const char *llvmArchToLegacyVCArch(llvm::Triple::ArchType Arch) {
684 using ArchType = llvm::Triple::ArchType;
685 switch (Arch) {
686 case ArchType::x86:
687 // x86 is default in legacy VC toolchains.
688 // e.g. x86 libs are directly in /lib as opposed to /lib/x86.
689 return "";
690 case ArchType::x86_64:
691 return "amd64";
692 case ArchType::arm:
693 return "arm";
694 default:
695 return "";
696 }
697}
698
699// Get the path to a specific subdirectory in the current toolchain for
700// a given target architecture.
701// VS2017 changed the VC toolchain layout, so this should be used instead
702// of hardcoding paths.
703std::string
704MSVCToolChain::getSubDirectoryPath(SubDirectoryType Type,
705 llvm::Triple::ArchType TargetArch) const {
706 llvm::SmallString<256> Path(VCToolChainPath);
707 switch (Type) {
708 case SubDirectoryType::Bin:
709 if (IsVS2017OrNewer) {
710 bool HostIsX64 =
711 llvm::Triple(llvm::sys::getProcessTriple()).isArch64Bit();
712 llvm::sys::path::append(Path, "bin", (HostIsX64 ? "HostX64" : "HostX86"),
713 llvmArchToWindowsSDKArch(TargetArch));
714
715 } else {
716 llvm::sys::path::append(Path, "bin", llvmArchToLegacyVCArch(TargetArch));
717 }
718 break;
719 case SubDirectoryType::Include:
720 llvm::sys::path::append(Path, "include");
721 break;
722 case SubDirectoryType::Lib:
723 llvm::sys::path::append(
724 Path, "lib", IsVS2017OrNewer ? llvmArchToWindowsSDKArch(TargetArch)
725 : llvmArchToLegacyVCArch(TargetArch));
726 break;
727 }
728 return Path.str();
729}
730
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000731#ifdef USE_WIN32
732static bool readFullStringValue(HKEY hkey, const char *valueName,
733 std::string &value) {
Aaron Ballmanb06a3592016-06-23 14:33:53 +0000734 std::wstring WideValueName;
735 if (!llvm::ConvertUTF8toWide(valueName, WideValueName))
736 return false;
737
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000738 DWORD result = 0;
739 DWORD valueSize = 0;
740 DWORD type = 0;
741 // First just query for the required size.
Aaron Ballmanb06a3592016-06-23 14:33:53 +0000742 result = RegQueryValueExW(hkey, WideValueName.c_str(), NULL, &type, NULL,
743 &valueSize);
744 if (result != ERROR_SUCCESS || type != REG_SZ || !valueSize)
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000745 return false;
746 std::vector<BYTE> buffer(valueSize);
Aaron Ballmanb06a3592016-06-23 14:33:53 +0000747 result = RegQueryValueExW(hkey, WideValueName.c_str(), NULL, NULL, &buffer[0],
748 &valueSize);
749 if (result == ERROR_SUCCESS) {
750 std::wstring WideValue(reinterpret_cast<const wchar_t *>(buffer.data()),
751 valueSize / sizeof(wchar_t));
Zachary Turnere78a3472016-07-28 17:13:32 +0000752 if (valueSize && WideValue.back() == L'\0') {
Etienne Bergeron982a3bc2016-08-30 18:38:25 +0000753 WideValue.pop_back();
Zachary Turnere78a3472016-07-28 17:13:32 +0000754 }
Aaron Ballmanb06a3592016-06-23 14:33:53 +0000755 // The destination buffer must be empty as an invariant of the conversion
756 // function; but this function is sometimes called in a loop that passes in
757 // the same buffer, however. Simply clear it out so we can overwrite it.
758 value.clear();
759 return llvm::convertWideToUTF8(WideValue, value);
760 }
761 return false;
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000762}
763#endif
764
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000765/// \brief Read registry string.
766/// This also supports a means to look for high-versioned keys by use
767/// of a $VERSION placeholder in the key path.
768/// $VERSION in the key path is a placeholder for the version number,
769/// causing the highest value path to be searched for and used.
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000770/// I.e. "SOFTWARE\\Microsoft\\VisualStudio\\$VERSION".
771/// There can be additional characters in the component. Only the numeric
772/// characters are compared. This function only searches HKLM.
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000773static bool getSystemRegistryString(const char *keyPath, const char *valueName,
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000774 std::string &value, std::string *phValue) {
Alp Tokerfcce1832014-06-22 03:27:45 +0000775#ifndef USE_WIN32
776 return false;
777#else
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000778 HKEY hRootKey = HKEY_LOCAL_MACHINE;
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000779 HKEY hKey = NULL;
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000780 long lResult;
781 bool returnValue = false;
782
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000783 const char *placeHolder = strstr(keyPath, "$VERSION");
784 std::string bestName;
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000785 // If we have a $VERSION placeholder, do the highest-version search.
786 if (placeHolder) {
787 const char *keyEnd = placeHolder - 1;
788 const char *nextKey = placeHolder;
789 // Find end of previous key.
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000790 while ((keyEnd > keyPath) && (*keyEnd != '\\'))
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000791 keyEnd--;
792 // Find end of key containing $VERSION.
793 while (*nextKey && (*nextKey != '\\'))
794 nextKey++;
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000795 size_t partialKeyLength = keyEnd - keyPath;
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000796 char partialKey[256];
Daniel Marjamakie1146692016-01-27 07:33:50 +0000797 if (partialKeyLength >= sizeof(partialKey))
798 partialKeyLength = sizeof(partialKey) - 1;
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000799 strncpy(partialKey, keyPath, partialKeyLength);
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000800 partialKey[partialKeyLength] = '\0';
801 HKEY hTopKey = NULL;
Aaron Ballmanb06a3592016-06-23 14:33:53 +0000802 lResult = RegOpenKeyExA(hRootKey, partialKey, 0, KEY_READ | KEY_WOW64_32KEY,
803 &hTopKey);
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000804 if (lResult == ERROR_SUCCESS) {
805 char keyName[256];
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000806 double bestValue = 0.0;
807 DWORD index, size = sizeof(keyName) - 1;
Aaron Ballmanb06a3592016-06-23 14:33:53 +0000808 for (index = 0; RegEnumKeyExA(hTopKey, index, keyName, &size, NULL, NULL,
809 NULL, NULL) == ERROR_SUCCESS;
810 index++) {
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000811 const char *sp = keyName;
Jordan Rosea7d03842013-02-08 22:30:41 +0000812 while (*sp && !isDigit(*sp))
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000813 sp++;
814 if (!*sp)
815 continue;
816 const char *ep = sp + 1;
Jordan Rosea7d03842013-02-08 22:30:41 +0000817 while (*ep && (isDigit(*ep) || (*ep == '.')))
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000818 ep++;
819 char numBuf[32];
820 strncpy(numBuf, sp, sizeof(numBuf) - 1);
821 numBuf[sizeof(numBuf) - 1] = '\0';
Hans Wennborgd2192312013-10-10 18:03:08 +0000822 double dvalue = strtod(numBuf, NULL);
823 if (dvalue > bestValue) {
824 // Test that InstallDir is indeed there before keeping this index.
825 // Open the chosen key path remainder.
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000826 bestName = keyName;
Hans Wennborgd2192312013-10-10 18:03:08 +0000827 // Append rest of key.
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000828 bestName.append(nextKey);
Aaron Ballmanb06a3592016-06-23 14:33:53 +0000829 lResult = RegOpenKeyExA(hTopKey, bestName.c_str(), 0,
830 KEY_READ | KEY_WOW64_32KEY, &hKey);
Hans Wennborgd2192312013-10-10 18:03:08 +0000831 if (lResult == ERROR_SUCCESS) {
Zachary Turnere78a3472016-07-28 17:13:32 +0000832 if (readFullStringValue(hKey, valueName, value)) {
Hans Wennborgd2192312013-10-10 18:03:08 +0000833 bestValue = dvalue;
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000834 if (phValue)
835 *phValue = bestName;
Hans Wennborgd2192312013-10-10 18:03:08 +0000836 returnValue = true;
837 }
838 RegCloseKey(hKey);
839 }
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000840 }
841 size = sizeof(keyName) - 1;
842 }
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000843 RegCloseKey(hTopKey);
844 }
845 } else {
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000846 lResult =
Aaron Ballmanb06a3592016-06-23 14:33:53 +0000847 RegOpenKeyExA(hRootKey, keyPath, 0, KEY_READ | KEY_WOW64_32KEY, &hKey);
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000848 if (lResult == ERROR_SUCCESS) {
Zachary Turnere78a3472016-07-28 17:13:32 +0000849 if (readFullStringValue(hKey, valueName, value))
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000850 returnValue = true;
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000851 if (phValue)
852 phValue->clear();
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000853 RegCloseKey(hKey);
854 }
855 }
856 return returnValue;
Alp Tokerfcce1832014-06-22 03:27:45 +0000857#endif // USE_WIN32
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000858}
859
Igor Kudrinf2e75242015-09-24 05:16:36 +0000860// Find the most recent version of Universal CRT or Windows 10 SDK.
861// vcvarsqueryregistry.bat from Visual Studio 2015 sorts entries in the include
862// directory by name and uses the last one of the list.
863// So we compare entry names lexicographically to find the greatest one.
Zachary Turnerf6302522017-03-15 16:07:35 +0000864static bool getWindows10SDKVersionFromPath(const std::string &SDKPath,
865 std::string &SDKVersion) {
Igor Kudrinf2e75242015-09-24 05:16:36 +0000866 SDKVersion.clear();
867
868 std::error_code EC;
869 llvm::SmallString<128> IncludePath(SDKPath);
870 llvm::sys::path::append(IncludePath, "Include");
871 for (llvm::sys::fs::directory_iterator DirIt(IncludePath, EC), DirEnd;
872 DirIt != DirEnd && !EC; DirIt.increment(EC)) {
873 if (!llvm::sys::fs::is_directory(DirIt->path()))
874 continue;
875 StringRef CandidateName = llvm::sys::path::filename(DirIt->path());
876 // If WDK is installed, there could be subfolders like "wdf" in the
877 // "Include" directory.
878 // Allow only directories which names start with "10.".
879 if (!CandidateName.startswith("10."))
880 continue;
881 if (CandidateName > SDKVersion)
882 SDKVersion = CandidateName;
883 }
884
885 return !SDKVersion.empty();
886}
887
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000888/// \brief Get Windows SDK installation directory.
Zachary Turnerf6302522017-03-15 16:07:35 +0000889static bool getWindowsSDKDir(std::string &Path, int &Major,
890 std::string &WindowsSDKIncludeVersion,
891 std::string &WindowsSDKLibVersion) {
Igor Kudrinf2e75242015-09-24 05:16:36 +0000892 std::string RegistrySDKVersion;
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000893 // Try the Windows registry.
Igor Kudrinf2e75242015-09-24 05:16:36 +0000894 if (!getSystemRegistryString(
895 "SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\$VERSION",
896 "InstallationFolder", Path, &RegistrySDKVersion))
897 return false;
898 if (Path.empty() || RegistrySDKVersion.empty())
899 return false;
900
901 WindowsSDKIncludeVersion.clear();
902 WindowsSDKLibVersion.clear();
903 Major = 0;
904 std::sscanf(RegistrySDKVersion.c_str(), "v%d.", &Major);
905 if (Major <= 7)
906 return true;
907 if (Major == 8) {
908 // Windows SDK 8.x installs libraries in a folder whose names depend on the
909 // version of the OS you're targeting. By default choose the newest, which
910 // usually corresponds to the version of the OS you've installed the SDK on.
911 const char *Tests[] = {"winv6.3", "win8", "win7"};
912 for (const char *Test : Tests) {
913 llvm::SmallString<128> TestPath(Path);
914 llvm::sys::path::append(TestPath, "Lib", Test);
915 if (llvm::sys::fs::exists(TestPath.c_str())) {
916 WindowsSDKLibVersion = Test;
917 break;
918 }
919 }
920 return !WindowsSDKLibVersion.empty();
921 }
922 if (Major == 10) {
Zachary Turnerf6302522017-03-15 16:07:35 +0000923 if (!getWindows10SDKVersionFromPath(Path, WindowsSDKIncludeVersion))
Igor Kudrinf2e75242015-09-24 05:16:36 +0000924 return false;
925 WindowsSDKLibVersion = WindowsSDKIncludeVersion;
926 return true;
927 }
928 // Unsupported SDK version
929 return false;
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000930}
931
Zachary Turner10d75b22014-10-22 20:40:43 +0000932// Gets the library path required to link against the Windows SDK.
933bool MSVCToolChain::getWindowsSDKLibraryPath(std::string &path) const {
934 std::string sdkPath;
935 int sdkMajor = 0;
Igor Kudrinf2e75242015-09-24 05:16:36 +0000936 std::string windowsSDKIncludeVersion;
937 std::string windowsSDKLibVersion;
Zachary Turner10d75b22014-10-22 20:40:43 +0000938
939 path.clear();
Igor Kudrinf2e75242015-09-24 05:16:36 +0000940 if (!getWindowsSDKDir(sdkPath, sdkMajor, windowsSDKIncludeVersion,
941 windowsSDKLibVersion))
Zachary Turner10d75b22014-10-22 20:40:43 +0000942 return false;
943
944 llvm::SmallString<128> libPath(sdkPath);
945 llvm::sys::path::append(libPath, "Lib");
Zachary Turnerf6302522017-03-15 16:07:35 +0000946 if (sdkMajor >= 8) {
947 llvm::sys::path::append(libPath, windowsSDKLibVersion, "um",
948 llvmArchToWindowsSDKArch(getArch()));
949 } else {
Zachary Turner10d75b22014-10-22 20:40:43 +0000950 switch (getArch()) {
Reid Klecknerbf183552017-02-02 19:36:22 +0000951 // In Windows SDK 7.x, x86 libraries are directly in the Lib folder.
Zachary Turner10d75b22014-10-22 20:40:43 +0000952 case llvm::Triple::x86:
953 break;
954 case llvm::Triple::x86_64:
955 llvm::sys::path::append(libPath, "x64");
956 break;
957 case llvm::Triple::arm:
958 // It is not necessary to link against Windows SDK 7.x when targeting ARM.
959 return false;
960 default:
961 return false;
962 }
Zachary Turner10d75b22014-10-22 20:40:43 +0000963 }
964
965 path = libPath.str();
966 return true;
967}
968
Reid Kleckner7531f7d2015-09-11 00:09:39 +0000969// Check if the Include path of a specified version of Visual Studio contains
970// specific header files. If not, they are probably shipped with Universal CRT.
Zachary Turnerf6302522017-03-15 16:07:35 +0000971bool MSVCToolChain::useUniversalCRT() const {
972 llvm::SmallString<128> TestPath(
973 getSubDirectoryPath(SubDirectoryType::Include));
974 llvm::sys::path::append(TestPath, "stdlib.h");
Reid Kleckner7531f7d2015-09-11 00:09:39 +0000975 return !llvm::sys::fs::exists(TestPath);
976}
977
Zachary Turnerf6302522017-03-15 16:07:35 +0000978static bool getUniversalCRTSdkDir(std::string &Path, std::string &UCRTVersion) {
Reid Kleckner7531f7d2015-09-11 00:09:39 +0000979 // vcvarsqueryregistry.bat for Visual Studio 2015 queries the registry
980 // for the specific key "KitsRoot10". So do we.
981 if (!getSystemRegistryString(
Reid Klecknerbf183552017-02-02 19:36:22 +0000982 "SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots", "KitsRoot10",
983 Path, nullptr))
Reid Kleckner7531f7d2015-09-11 00:09:39 +0000984 return false;
985
Zachary Turnerf6302522017-03-15 16:07:35 +0000986 return getWindows10SDKVersionFromPath(Path, UCRTVersion);
Reid Kleckner7531f7d2015-09-11 00:09:39 +0000987}
988
989bool MSVCToolChain::getUniversalCRTLibraryPath(std::string &Path) const {
990 std::string UniversalCRTSdkPath;
991 std::string UCRTVersion;
992
993 Path.clear();
994 if (!getUniversalCRTSdkDir(UniversalCRTSdkPath, UCRTVersion))
995 return false;
996
Zachary Turnerf6302522017-03-15 16:07:35 +0000997 StringRef ArchName = llvmArchToWindowsSDKArch(getArch());
Reid Kleckner7531f7d2015-09-11 00:09:39 +0000998 if (ArchName.empty())
999 return false;
1000
1001 llvm::SmallString<128> LibPath(UniversalCRTSdkPath);
1002 llvm::sys::path::append(LibPath, "Lib", UCRTVersion, "ucrt", ArchName);
1003
1004 Path = LibPath.str();
1005 return true;
1006}
1007
Zachary Turnerf6302522017-03-15 16:07:35 +00001008static VersionTuple getMSVCVersionFromTriple(const llvm::Triple &Triple) {
David L. Jones24fb20c2016-12-07 23:41:58 +00001009 unsigned Major, Minor, Micro;
Zachary Turnerf6302522017-03-15 16:07:35 +00001010 Triple.getEnvironmentVersion(Major, Minor, Micro);
David L. Jones24fb20c2016-12-07 23:41:58 +00001011 if (Major || Minor || Micro)
1012 return VersionTuple(Major, Minor, Micro);
1013 return VersionTuple();
1014}
1015
Zachary Turnerf6302522017-03-15 16:07:35 +00001016static VersionTuple getMSVCVersionFromExe(const std::string &BinDir) {
Adrian McCarthye4b26fc2016-05-13 23:20:11 +00001017 VersionTuple Version;
1018#ifdef USE_WIN32
Zachary Turnerf6302522017-03-15 16:07:35 +00001019 SmallString<128> ClExe(BinDir);
Adrian McCarthye4b26fc2016-05-13 23:20:11 +00001020 llvm::sys::path::append(ClExe, "cl.exe");
1021
1022 std::wstring ClExeWide;
1023 if (!llvm::ConvertUTF8toWide(ClExe.c_str(), ClExeWide))
1024 return Version;
1025
1026 const DWORD VersionSize = ::GetFileVersionInfoSizeW(ClExeWide.c_str(),
1027 nullptr);
1028 if (VersionSize == 0)
1029 return Version;
1030
1031 SmallVector<uint8_t, 4 * 1024> VersionBlock(VersionSize);
1032 if (!::GetFileVersionInfoW(ClExeWide.c_str(), 0, VersionSize,
1033 VersionBlock.data()))
1034 return Version;
1035
1036 VS_FIXEDFILEINFO *FileInfo = nullptr;
1037 UINT FileInfoSize = 0;
1038 if (!::VerQueryValueW(VersionBlock.data(), L"\\",
1039 reinterpret_cast<LPVOID *>(&FileInfo), &FileInfoSize) ||
1040 FileInfoSize < sizeof(*FileInfo))
1041 return Version;
1042
1043 const unsigned Major = (FileInfo->dwFileVersionMS >> 16) & 0xFFFF;
1044 const unsigned Minor = (FileInfo->dwFileVersionMS ) & 0xFFFF;
1045 const unsigned Micro = (FileInfo->dwFileVersionLS >> 16) & 0xFFFF;
1046
1047 Version = VersionTuple(Major, Minor, Micro);
1048#endif
1049 return Version;
1050}
1051
Igor Kudrinf2e75242015-09-24 05:16:36 +00001052void MSVCToolChain::AddSystemIncludeWithSubfolder(
1053 const ArgList &DriverArgs, ArgStringList &CC1Args,
1054 const std::string &folder, const Twine &subfolder1, const Twine &subfolder2,
1055 const Twine &subfolder3) const {
Zachary Turner0eaf8fc2014-10-22 20:40:28 +00001056 llvm::SmallString<128> path(folder);
Igor Kudrinf2e75242015-09-24 05:16:36 +00001057 llvm::sys::path::append(path, subfolder1, subfolder2, subfolder3);
Yaron Keren92e1b622015-03-18 10:17:07 +00001058 addSystemInclude(DriverArgs, CC1Args, path);
Zachary Turner0eaf8fc2014-10-22 20:40:28 +00001059}
1060
Saleem Abdulrasool819f3912014-10-22 02:37:29 +00001061void MSVCToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
1062 ArgStringList &CC1Args) const {
Chandler Carruth1fc603e2011-12-17 23:10:01 +00001063 if (DriverArgs.hasArg(options::OPT_nostdinc))
1064 return;
1065
1066 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
Igor Kudrinf2e75242015-09-24 05:16:36 +00001067 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, getDriver().ResourceDir,
1068 "include");
Chandler Carruth1fc603e2011-12-17 23:10:01 +00001069 }
1070
Nico Weberfd3e1ad2016-04-12 19:04:37 +00001071 // Add %INCLUDE%-like directories from the -imsvc flag.
1072 for (const auto &Path : DriverArgs.getAllArgValues(options::OPT__SLASH_imsvc))
1073 addSystemInclude(DriverArgs, CC1Args, Path);
1074
Chandler Carruth1fc603e2011-12-17 23:10:01 +00001075 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
1076 return;
1077
Joao Matos792d7af2012-09-04 17:29:52 +00001078 // Honor %INCLUDE%. It should know essential search paths with vcvarsall.bat.
David Majnemer85c25b42016-07-24 17:44:03 +00001079 if (llvm::Optional<std::string> cl_include_dir =
1080 llvm::sys::Process::GetEnv("INCLUDE")) {
Joao Matos792d7af2012-09-04 17:29:52 +00001081 SmallVector<StringRef, 8> Dirs;
David Majnemer85c25b42016-07-24 17:44:03 +00001082 StringRef(*cl_include_dir)
Reid Kleckner77b45ba2014-04-23 00:15:01 +00001083 .split(Dirs, ";", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
1084 for (StringRef Dir : Dirs)
1085 addSystemInclude(DriverArgs, CC1Args, Dir);
1086 if (!Dirs.empty())
1087 return;
Joao Matos792d7af2012-09-04 17:29:52 +00001088 }
1089
Joao Matos792d7af2012-09-04 17:29:52 +00001090 // When built with access to the proper Windows APIs, try to actually find
1091 // the correct include paths first.
Zachary Turnerf6302522017-03-15 16:07:35 +00001092 if (!VCToolChainPath.empty()) {
1093 addSystemInclude(DriverArgs, CC1Args,
1094 getSubDirectoryPath(SubDirectoryType::Include));
Zachary Turner0eaf8fc2014-10-22 20:40:28 +00001095
Zachary Turnerf6302522017-03-15 16:07:35 +00001096 if (useUniversalCRT()) {
Reid Kleckner7531f7d2015-09-11 00:09:39 +00001097 std::string UniversalCRTSdkPath;
1098 std::string UCRTVersion;
1099 if (getUniversalCRTSdkDir(UniversalCRTSdkPath, UCRTVersion)) {
Igor Kudrinf2e75242015-09-24 05:16:36 +00001100 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, UniversalCRTSdkPath,
1101 "Include", UCRTVersion, "ucrt");
Reid Kleckner7531f7d2015-09-11 00:09:39 +00001102 }
1103 }
1104
Zachary Turner0eaf8fc2014-10-22 20:40:28 +00001105 std::string WindowsSDKDir;
Igor Kudrinf2e75242015-09-24 05:16:36 +00001106 int major;
1107 std::string windowsSDKIncludeVersion;
1108 std::string windowsSDKLibVersion;
1109 if (getWindowsSDKDir(WindowsSDKDir, major, windowsSDKIncludeVersion,
1110 windowsSDKLibVersion)) {
Zachary Turner0eaf8fc2014-10-22 20:40:28 +00001111 if (major >= 8) {
Igor Kudrinf2e75242015-09-24 05:16:36 +00001112 // Note: windowsSDKIncludeVersion is empty for SDKs prior to v10.
1113 // Anyway, llvm::sys::path::append is able to manage it.
Zachary Turner0eaf8fc2014-10-22 20:40:28 +00001114 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
Igor Kudrinf2e75242015-09-24 05:16:36 +00001115 "include", windowsSDKIncludeVersion,
1116 "shared");
Zachary Turner0eaf8fc2014-10-22 20:40:28 +00001117 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
Igor Kudrinf2e75242015-09-24 05:16:36 +00001118 "include", windowsSDKIncludeVersion,
1119 "um");
Zachary Turner0eaf8fc2014-10-22 20:40:28 +00001120 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
Igor Kudrinf2e75242015-09-24 05:16:36 +00001121 "include", windowsSDKIncludeVersion,
1122 "winrt");
Zachary Turner0eaf8fc2014-10-22 20:40:28 +00001123 } else {
1124 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
1125 "include");
1126 }
Reid Kleckner77b45ba2014-04-23 00:15:01 +00001127 }
Zachary Turnerf6302522017-03-15 16:07:35 +00001128
Joao Matos792d7af2012-09-04 17:29:52 +00001129 return;
1130 }
Joao Matos792d7af2012-09-04 17:29:52 +00001131
David Majnemerd5f7d192016-07-25 04:47:44 +00001132#if defined(LLVM_ON_WIN32)
Joao Matos792d7af2012-09-04 17:29:52 +00001133 // As a fallback, select default install paths.
Alp Tokerfcce1832014-06-22 03:27:45 +00001134 // FIXME: Don't guess drives and paths like this on Windows.
Joao Matos792d7af2012-09-04 17:29:52 +00001135 const StringRef Paths[] = {
1136 "C:/Program Files/Microsoft Visual Studio 10.0/VC/include",
1137 "C:/Program Files/Microsoft Visual Studio 9.0/VC/include",
1138 "C:/Program Files/Microsoft Visual Studio 9.0/VC/PlatformSDK/Include",
1139 "C:/Program Files/Microsoft Visual Studio 8/VC/include",
1140 "C:/Program Files/Microsoft Visual Studio 8/VC/PlatformSDK/Include"
1141 };
1142 addSystemIncludes(DriverArgs, CC1Args, Paths);
David Majnemerd5f7d192016-07-25 04:47:44 +00001143#endif
Chandler Carruth1fc603e2011-12-17 23:10:01 +00001144}
1145
Saleem Abdulrasool819f3912014-10-22 02:37:29 +00001146void MSVCToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
1147 ArgStringList &CC1Args) const {
Chandler Carruth1fc603e2011-12-17 23:10:01 +00001148 // FIXME: There should probably be logic here to find libc++ on Windows.
1149}
David Majnemere11d3732015-06-08 00:22:46 +00001150
David L. Jones24fb20c2016-12-07 23:41:58 +00001151VersionTuple MSVCToolChain::computeMSVCVersion(const Driver *D,
1152 const ArgList &Args) const {
1153 bool IsWindowsMSVC = getTriple().isWindowsMSVCEnvironment();
1154 VersionTuple MSVT = ToolChain::computeMSVCVersion(D, Args);
Zachary Turnerf6302522017-03-15 16:07:35 +00001155 if (MSVT.empty())
1156 MSVT = getMSVCVersionFromTriple(getTriple());
1157 if (MSVT.empty() && IsWindowsMSVC)
1158 MSVT = getMSVCVersionFromExe(getSubDirectoryPath(SubDirectoryType::Bin));
David L. Jones24fb20c2016-12-07 23:41:58 +00001159 if (MSVT.empty() &&
1160 Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions,
1161 IsWindowsMSVC)) {
1162 // -fms-compatibility-version=18.00 is default.
1163 // FIXME: Consider bumping this to 19 (MSVC2015) soon.
1164 MSVT = VersionTuple(18);
1165 }
1166 return MSVT;
1167}
1168
David Majnemere11d3732015-06-08 00:22:46 +00001169std::string
1170MSVCToolChain::ComputeEffectiveClangTriple(const ArgList &Args,
1171 types::ID InputType) const {
David L. Jones24fb20c2016-12-07 23:41:58 +00001172 // The MSVC version doesn't care about the architecture, even though it
1173 // may look at the triple internally.
1174 VersionTuple MSVT = computeMSVCVersion(/*D=*/nullptr, Args);
David Majnemere11d3732015-06-08 00:22:46 +00001175 MSVT = VersionTuple(MSVT.getMajor(), MSVT.getMinor().getValueOr(0),
1176 MSVT.getSubminor().getValueOr(0));
1177
David L. Jones24fb20c2016-12-07 23:41:58 +00001178 // For the rest of the triple, however, a computed architecture name may
1179 // be needed.
1180 llvm::Triple Triple(ToolChain::ComputeEffectiveClangTriple(Args, InputType));
David Majnemer75fdd6b2015-06-09 06:30:01 +00001181 if (Triple.getEnvironment() == llvm::Triple::MSVC) {
1182 StringRef ObjFmt = Triple.getEnvironmentName().split('-').second;
1183 if (ObjFmt.empty())
1184 Triple.setEnvironmentName((Twine("msvc") + MSVT.getAsString()).str());
1185 else
1186 Triple.setEnvironmentName(
1187 (Twine("msvc") + MSVT.getAsString() + Twine('-') + ObjFmt).str());
1188 }
David Majnemere11d3732015-06-08 00:22:46 +00001189 return Triple.getTriple();
1190}
Alexey Samsonov7f2a0d22015-06-19 21:36:47 +00001191
1192SanitizerMask MSVCToolChain::getSupportedSanitizers() const {
1193 SanitizerMask Res = ToolChain::getSupportedSanitizers();
1194 Res |= SanitizerKind::Address;
Alexey Samsonov7f2a0d22015-06-19 21:36:47 +00001195 return Res;
1196}
David Majnemer015ce0f2015-07-27 07:32:11 +00001197
Hans Wennborg21d73d22016-01-12 23:17:03 +00001198static void TranslateOptArg(Arg *A, llvm::opt::DerivedArgList &DAL,
1199 bool SupportsForcingFramePointer,
1200 const char *ExpandChar, const OptTable &Opts) {
1201 assert(A->getOption().matches(options::OPT__SLASH_O));
1202
1203 StringRef OptStr = A->getValue();
1204 for (size_t I = 0, E = OptStr.size(); I != E; ++I) {
1205 const char &OptChar = *(OptStr.data() + I);
1206 switch (OptChar) {
1207 default:
1208 break;
1209 case '1':
1210 case '2':
1211 case 'x':
1212 case 'd':
1213 if (&OptChar == ExpandChar) {
1214 if (OptChar == 'd') {
1215 DAL.AddFlagArg(A, Opts.getOption(options::OPT_O0));
1216 } else {
1217 if (OptChar == '1') {
1218 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "s");
1219 } else if (OptChar == '2' || OptChar == 'x') {
1220 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
1221 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "2");
1222 }
David Majnemer259d71a2016-01-21 23:01:11 +00001223 if (SupportsForcingFramePointer &&
1224 !DAL.hasArgNoClaim(options::OPT_fno_omit_frame_pointer))
Hans Wennborg21d73d22016-01-12 23:17:03 +00001225 DAL.AddFlagArg(A,
1226 Opts.getOption(options::OPT_fomit_frame_pointer));
1227 if (OptChar == '1' || OptChar == '2')
1228 DAL.AddFlagArg(A,
1229 Opts.getOption(options::OPT_ffunction_sections));
1230 }
1231 }
1232 break;
1233 case 'b':
Hans Wennborg3270bdb2016-05-24 21:23:29 +00001234 if (I + 1 != E && isdigit(OptStr[I + 1])) {
1235 switch (OptStr[I + 1]) {
1236 case '0':
1237 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_inline));
1238 break;
1239 case '1':
Hans Wennborg44d061a2016-06-22 16:56:16 +00001240 DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_hint_functions));
Hans Wennborg3270bdb2016-05-24 21:23:29 +00001241 break;
1242 case '2':
1243 DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_functions));
1244 break;
1245 }
Hans Wennborg21d73d22016-01-12 23:17:03 +00001246 ++I;
Hans Wennborg3270bdb2016-05-24 21:23:29 +00001247 }
Hans Wennborg21d73d22016-01-12 23:17:03 +00001248 break;
1249 case 'g':
1250 break;
1251 case 'i':
1252 if (I + 1 != E && OptStr[I + 1] == '-') {
1253 ++I;
1254 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_builtin));
1255 } else {
1256 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
1257 }
1258 break;
1259 case 's':
1260 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "s");
1261 break;
1262 case 't':
1263 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "2");
1264 break;
1265 case 'y': {
1266 bool OmitFramePointer = true;
1267 if (I + 1 != E && OptStr[I + 1] == '-') {
1268 OmitFramePointer = false;
1269 ++I;
1270 }
1271 if (SupportsForcingFramePointer) {
1272 if (OmitFramePointer)
1273 DAL.AddFlagArg(A,
1274 Opts.getOption(options::OPT_fomit_frame_pointer));
1275 else
1276 DAL.AddFlagArg(
1277 A, Opts.getOption(options::OPT_fno_omit_frame_pointer));
Nico Weber9c3fca32016-03-23 15:37:41 +00001278 } else {
1279 // Don't warn about /Oy- in 64-bit builds (where
1280 // SupportsForcingFramePointer is false). The flag having no effect
1281 // there is a compiler-internal optimization, and people shouldn't have
1282 // to special-case their build files for 64-bit clang-cl.
1283 A->claim();
Hans Wennborg21d73d22016-01-12 23:17:03 +00001284 }
1285 break;
1286 }
1287 }
1288 }
1289}
1290
1291static void TranslateDArg(Arg *A, llvm::opt::DerivedArgList &DAL,
1292 const OptTable &Opts) {
1293 assert(A->getOption().matches(options::OPT_D));
1294
1295 StringRef Val = A->getValue();
1296 size_t Hash = Val.find('#');
1297 if (Hash == StringRef::npos || Hash > Val.find('=')) {
1298 DAL.append(A);
1299 return;
1300 }
1301
1302 std::string NewVal = Val;
1303 NewVal[Hash] = '=';
1304 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_D), NewVal);
1305}
1306
David Majnemer015ce0f2015-07-27 07:32:11 +00001307llvm::opt::DerivedArgList *
1308MSVCToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args,
Samuel Antao31fef982016-10-27 17:39:44 +00001309 StringRef BoundArch, Action::OffloadKind) const {
David Majnemer015ce0f2015-07-27 07:32:11 +00001310 DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
1311 const OptTable &Opts = getDriver().getOpts();
1312
David Majnemer7ab76f22015-08-25 00:46:45 +00001313 // /Oy and /Oy- only has an effect under X86-32.
1314 bool SupportsForcingFramePointer = getArch() == llvm::Triple::x86;
1315
David Majnemer015ce0f2015-07-27 07:32:11 +00001316 // The -O[12xd] flag actually expands to several flags. We must desugar the
1317 // flags so that options embedded can be negated. For example, the '-O2' flag
1318 // enables '-Oy'. Expanding '-O2' into its constituent flags allows us to
1319 // correctly handle '-O2 -Oy-' where the trailing '-Oy-' disables a single
1320 // aspect of '-O2'.
1321 //
1322 // Note that this expansion logic only applies to the *last* of '[12xd]'.
1323
1324 // First step is to search for the character we'd like to expand.
1325 const char *ExpandChar = nullptr;
1326 for (Arg *A : Args) {
1327 if (!A->getOption().matches(options::OPT__SLASH_O))
1328 continue;
1329 StringRef OptStr = A->getValue();
1330 for (size_t I = 0, E = OptStr.size(); I != E; ++I) {
Hans Wennborgdebfed92016-05-25 00:43:45 +00001331 char OptChar = OptStr[I];
1332 char PrevChar = I > 0 ? OptStr[I - 1] : '0';
1333 if (PrevChar == 'b') {
1334 // OptChar does not expand; it's an argument to the previous char.
1335 continue;
1336 }
David Majnemer015ce0f2015-07-27 07:32:11 +00001337 if (OptChar == '1' || OptChar == '2' || OptChar == 'x' || OptChar == 'd')
1338 ExpandChar = OptStr.data() + I;
1339 }
1340 }
1341
David Majnemer015ce0f2015-07-27 07:32:11 +00001342 for (Arg *A : Args) {
Hans Wennborg21d73d22016-01-12 23:17:03 +00001343 if (A->getOption().matches(options::OPT__SLASH_O)) {
1344 // The -O flag actually takes an amalgam of other options. For example,
1345 // '/Ogyb2' is equivalent to '/Og' '/Oy' '/Ob2'.
1346 TranslateOptArg(A, *DAL, SupportsForcingFramePointer, ExpandChar, Opts);
1347 } else if (A->getOption().matches(options::OPT_D)) {
1348 // Translate -Dfoo#bar into -Dfoo=bar.
1349 TranslateDArg(A, *DAL, Opts);
1350 } else {
David Majnemer015ce0f2015-07-27 07:32:11 +00001351 DAL->append(A);
David Majnemer015ce0f2015-07-27 07:32:11 +00001352 }
1353 }
Hans Wennborg21d73d22016-01-12 23:17:03 +00001354
David Majnemer015ce0f2015-07-27 07:32:11 +00001355 return DAL;
1356}