blob: ce8e1b2b600d294535b74e15e2642cf44c1cd2a5 [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 Turnerf6302522017-03-15 16:07:35 +000047
48// Make sure this comes before MSVCSetupApi.h
49#include <comdef.h>
50
51#include "MSVCSetupApi.h"
52#include "llvm/Support/COM.h"
53_COM_SMARTPTR_TYPEDEF(ISetupConfiguration, __uuidof(ISetupConfiguration));
54_COM_SMARTPTR_TYPEDEF(ISetupConfiguration2, __uuidof(ISetupConfiguration2));
55_COM_SMARTPTR_TYPEDEF(ISetupHelper, __uuidof(ISetupHelper));
56_COM_SMARTPTR_TYPEDEF(IEnumSetupInstances, __uuidof(IEnumSetupInstances));
57_COM_SMARTPTR_TYPEDEF(ISetupInstance, __uuidof(ISetupInstance));
58_COM_SMARTPTR_TYPEDEF(ISetupInstance2, __uuidof(ISetupInstance2));
Chandler Carruth1fc603e2011-12-17 23:10:01 +000059#endif
60
61using namespace clang::driver;
62using namespace clang::driver::toolchains;
David L. Jonesf561aba2017-03-08 01:02:16 +000063using namespace clang::driver::tools;
Chandler Carruth1fc603e2011-12-17 23:10:01 +000064using namespace clang;
Reid Kleckner898229a2013-06-14 17:17:23 +000065using namespace llvm::opt;
Chandler Carruth1fc603e2011-12-17 23:10:01 +000066
Zachary Turnerf6302522017-03-15 16:07:35 +000067// Defined below.
68// Forward declare this so there aren't too many things above the constructor.
69static bool getSystemRegistryString(const char *keyPath, const char *valueName,
70 std::string &value, std::string *phValue);
71
72// Check various environment variables to try and find a toolchain.
73static bool findVCToolChainViaEnvironment(std::string &Path,
74 bool &IsVS2017OrNewer) {
75 // These variables are typically set by vcvarsall.bat
76 // when launching a developer command prompt.
77 if (llvm::Optional<std::string> VCToolsInstallDir =
78 llvm::sys::Process::GetEnv("VCToolsInstallDir")) {
79 // This is only set by newer Visual Studios, and it leads straight to
80 // the toolchain directory.
81 Path = std::move(*VCToolsInstallDir);
82 IsVS2017OrNewer = true;
83 return true;
84 }
85 if (llvm::Optional<std::string> VCInstallDir =
86 llvm::sys::Process::GetEnv("VCINSTALLDIR")) {
87 // If the previous variable isn't set but this one is, then we've found
88 // an older Visual Studio. This variable is set by newer Visual Studios too,
89 // so this check has to appear second.
90 // In older Visual Studios, the VC directory is the toolchain.
91 Path = std::move(*VCInstallDir);
92 IsVS2017OrNewer = false;
93 return true;
94 }
95
96 // We couldn't find any VC environment variables. Let's walk through PATH and
97 // see if it leads us to a VC toolchain bin directory. If it does, pick the
98 // first one that we find.
99 if (llvm::Optional<std::string> PathEnv =
100 llvm::sys::Process::GetEnv("PATH")) {
101 llvm::SmallVector<llvm::StringRef, 8> PathEntries;
102 llvm::StringRef(*PathEnv).split(PathEntries, llvm::sys::EnvPathSeparator);
103 for (llvm::StringRef PathEntry : PathEntries) {
104 if (PathEntry.empty())
105 continue;
106
107 llvm::SmallString<256> ExeTestPath;
108
109 // If cl.exe doesn't exist, then this definitely isn't a VC toolchain.
110 ExeTestPath = PathEntry;
111 llvm::sys::path::append(ExeTestPath, "cl.exe");
112 if (!llvm::sys::fs::exists(ExeTestPath))
113 continue;
114
115 // cl.exe existing isn't a conclusive test for a VC toolchain; clang also
116 // has a cl.exe. So let's check for link.exe too.
117 ExeTestPath = PathEntry;
118 llvm::sys::path::append(ExeTestPath, "link.exe");
119 if (!llvm::sys::fs::exists(ExeTestPath))
120 continue;
121
122 // whatever/VC/bin --> old toolchain, VC dir is toolchain dir.
123 if (llvm::sys::path::filename(PathEntry) == "bin") {
124 llvm::StringRef ParentPath = llvm::sys::path::parent_path(PathEntry);
125 if (llvm::sys::path::filename(ParentPath) == "VC") {
126 Path = ParentPath;
127 IsVS2017OrNewer = false;
128 return true;
129 }
130
131 } else {
132 // This could be a new (>=VS2017) toolchain. If it is, we should find
133 // path components with these prefixes when walking backwards through
134 // the path.
135 // Note: empty strings match anything.
136 llvm::StringRef ExpectedPrefixes[] = {"", "Host", "bin", "",
137 "MSVC", "Tools", "VC"};
138
139 auto It = llvm::sys::path::rbegin(PathEntry);
140 auto End = llvm::sys::path::rend(PathEntry);
141 for (llvm::StringRef Prefix : ExpectedPrefixes) {
142 if (It == End)
143 goto NotAToolChain;
144 if (!It->startswith(Prefix))
145 goto NotAToolChain;
146 ++It;
147 }
148
149 // We've found a new toolchain!
150 // Back up 3 times (/bin/Host/arch) to get the root path.
151 llvm::StringRef ToolChainPath(PathEntry);
152 for (int i = 0; i < 3; ++i)
153 ToolChainPath = llvm::sys::path::parent_path(ToolChainPath);
154
155 Path = ToolChainPath;
156 IsVS2017OrNewer = true;
157 return true;
158 }
159
160 NotAToolChain:
161 continue;
162 }
163 }
164 return false;
165}
166
167// Query the Setup Config server for installs, then pick the newest version
168// and find its default VC toolchain.
169// This is the preferred way to discover new Visual Studios, as they're no
170// longer listed in the registry.
171static bool findVCToolChainViaSetupConfig(std::string &Path,
172 bool &IsVS2017OrNewer) {
173#if !defined(USE_WIN32)
174 return false;
175#else
176 // FIXME: This really should be done once in the top-level program's main
177 // function, as it may have already been initialized with a different
178 // threading model otherwise.
179 llvm::sys::InitializeCOMRAII COM(llvm::sys::COMThreadingMode::SingleThreaded);
180 HRESULT HR;
181
182 // _com_ptr_t will throw a _com_error if a COM calls fail.
183 // The LLVM coding standards forbid exception handling, so we'll have to
184 // stop them from being thrown in the first place.
185 // The destructor will put the regular error handler back when we leave
186 // this scope.
187 struct SuppressCOMErrorsRAII {
188 static void __stdcall handler(HRESULT hr, IErrorInfo *perrinfo) {}
189
190 SuppressCOMErrorsRAII() { _set_com_error_handler(handler); }
191
192 ~SuppressCOMErrorsRAII() { _set_com_error_handler(_com_raise_error); }
193
194 } COMErrorSuppressor;
195
196 ISetupConfigurationPtr Query;
197 HR = Query.CreateInstance(__uuidof(SetupConfiguration));
198 if (FAILED(HR))
199 return false;
200
201 IEnumSetupInstancesPtr EnumInstances;
202 HR = ISetupConfiguration2Ptr(Query)->EnumAllInstances(&EnumInstances);
203 if (FAILED(HR))
204 return false;
205
206 ISetupInstancePtr Instance;
207 HR = EnumInstances->Next(1, &Instance, nullptr);
208 if (HR != S_OK)
209 return false;
210
211 ISetupInstancePtr NewestInstance;
212 Optional<uint64_t> NewestVersionNum;
213 do {
214 bstr_t VersionString;
215 uint64_t VersionNum;
216 HR = Instance->GetInstallationVersion(VersionString.GetAddress());
217 if (FAILED(HR))
218 continue;
219 HR = ISetupHelperPtr(Query)->ParseVersion(VersionString, &VersionNum);
220 if (FAILED(HR))
221 continue;
222 if (!NewestVersionNum || (VersionNum > NewestVersionNum)) {
223 NewestInstance = Instance;
224 NewestVersionNum = VersionNum;
225 }
226 } while ((HR = EnumInstances->Next(1, &Instance, nullptr)) == S_OK);
227
228 if (!NewestInstance)
229 return false;
230
231 bstr_t VCPathWide;
232 HR = NewestInstance->ResolvePath(L"VC", VCPathWide.GetAddress());
233 if (FAILED(HR))
234 return false;
235
236 std::string VCRootPath;
237 llvm::convertWideToUTF8(std::wstring(VCPathWide), VCRootPath);
238
239 llvm::SmallString<256> ToolsVersionFilePath(VCRootPath);
240 llvm::sys::path::append(ToolsVersionFilePath, "Auxiliary", "Build",
241 "Microsoft.VCToolsVersion.default.txt");
242
243 auto ToolsVersionFile = llvm::MemoryBuffer::getFile(ToolsVersionFilePath);
244 if (!ToolsVersionFile)
245 return false;
246
247 llvm::SmallString<256> ToolchainPath(VCRootPath);
248 llvm::sys::path::append(ToolchainPath, "Tools", "MSVC",
249 ToolsVersionFile->get()->getBuffer().rtrim());
250 if (!llvm::sys::fs::is_directory(ToolchainPath))
251 return false;
252
253 Path = ToolchainPath.str();
254 IsVS2017OrNewer = true;
255 return true;
256#endif
257}
258
259// Look in the registry for Visual Studio installs, and use that to get
260// a toolchain path. VS2017 and newer don't get added to the registry.
261// So if we find something here, we know that it's an older version.
262static bool findVCToolChainViaRegistry(std::string &Path,
263 bool &IsVS2017OrNewer) {
264 std::string VSInstallPath;
265 if (getSystemRegistryString(R"(SOFTWARE\Microsoft\VisualStudio\$VERSION)",
266 "InstallDir", VSInstallPath, nullptr) ||
267 getSystemRegistryString(R"(SOFTWARE\Microsoft\VCExpress\$VERSION)",
268 "InstallDir", VSInstallPath, nullptr)) {
269 if (!VSInstallPath.empty()) {
270 llvm::SmallString<256> VCPath(llvm::StringRef(
271 VSInstallPath.c_str(), VSInstallPath.find(R"(\Common7\IDE)")));
272 llvm::sys::path::append(VCPath, "VC");
273
274 Path = VCPath.str();
275 IsVS2017OrNewer = false;
276 return true;
277 }
278 }
279 return false;
280}
281
David L. Jonesf561aba2017-03-08 01:02:16 +0000282// Try to find Exe from a Visual Studio distribution. This first tries to find
283// an installed copy of Visual Studio and, failing that, looks in the PATH,
284// making sure that whatever executable that's found is not a same-named exe
285// from clang itself to prevent clang from falling back to itself.
286static std::string FindVisualStudioExecutable(const ToolChain &TC,
Zachary Turnerf6302522017-03-15 16:07:35 +0000287 const char *Exe) {
David L. Jonesf561aba2017-03-08 01:02:16 +0000288 const auto &MSVC = static_cast<const toolchains::MSVCToolChain &>(TC);
Zachary Turnerf6302522017-03-15 16:07:35 +0000289 SmallString<128> FilePath(MSVC.getSubDirectoryPath(
290 toolchains::MSVCToolChain::SubDirectoryType::Bin));
291 llvm::sys::path::append(FilePath, Exe);
292 return llvm::sys::fs::can_execute(FilePath) ? FilePath.str() : Exe;
David L. Jonesf561aba2017-03-08 01:02:16 +0000293}
294
295void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA,
296 const InputInfo &Output,
297 const InputInfoList &Inputs,
298 const ArgList &Args,
299 const char *LinkingOutput) const {
300 ArgStringList CmdArgs;
Zachary Turnerf6302522017-03-15 16:07:35 +0000301
302 auto &TC = static_cast<const toolchains::MSVCToolChain &>(getToolChain());
David L. Jonesf561aba2017-03-08 01:02:16 +0000303
304 assert((Output.isFilename() || Output.isNothing()) && "invalid output");
305 if (Output.isFilename())
306 CmdArgs.push_back(
307 Args.MakeArgString(std::string("-out:") + Output.getFilename()));
308
309 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles) &&
310 !C.getDriver().IsCLMode())
311 CmdArgs.push_back("-defaultlib:libcmt");
312
313 if (!llvm::sys::Process::GetEnv("LIB")) {
314 // If the VC environment hasn't been configured (perhaps because the user
315 // did not run vcvarsall), try to build a consistent link environment. If
316 // the environment variable is set however, assume the user knows what
317 // they're doing.
Zachary Turnerf6302522017-03-15 16:07:35 +0000318 CmdArgs.push_back(Args.MakeArgString(
319 Twine("-libpath:") +
320 TC.getSubDirectoryPath(
321 toolchains::MSVCToolChain::SubDirectoryType::Lib)));
David L. Jonesf561aba2017-03-08 01:02:16 +0000322
Zachary Turnerf6302522017-03-15 16:07:35 +0000323 if (TC.useUniversalCRT()) {
324 std::string UniversalCRTLibPath;
325 if (TC.getUniversalCRTLibraryPath(UniversalCRTLibPath))
326 CmdArgs.push_back(
327 Args.MakeArgString(Twine("-libpath:") + UniversalCRTLibPath));
David L. Jonesf561aba2017-03-08 01:02:16 +0000328 }
329
330 std::string WindowsSdkLibPath;
Zachary Turnerf6302522017-03-15 16:07:35 +0000331 if (TC.getWindowsSDKLibraryPath(WindowsSdkLibPath))
David L. Jonesf561aba2017-03-08 01:02:16 +0000332 CmdArgs.push_back(
333 Args.MakeArgString(std::string("-libpath:") + WindowsSdkLibPath));
334 }
335
336 if (!C.getDriver().IsCLMode() && Args.hasArg(options::OPT_L))
337 for (const auto &LibPath : Args.getAllArgValues(options::OPT_L))
338 CmdArgs.push_back(Args.MakeArgString("-libpath:" + LibPath));
339
340 CmdArgs.push_back("-nologo");
341
342 if (Args.hasArg(options::OPT_g_Group, options::OPT__SLASH_Z7,
343 options::OPT__SLASH_Zd))
344 CmdArgs.push_back("-debug");
345
346 bool DLL = Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd,
347 options::OPT_shared);
348 if (DLL) {
349 CmdArgs.push_back(Args.MakeArgString("-dll"));
350
351 SmallString<128> ImplibName(Output.getFilename());
352 llvm::sys::path::replace_extension(ImplibName, "lib");
353 CmdArgs.push_back(Args.MakeArgString(std::string("-implib:") + ImplibName));
354 }
355
356 if (TC.getSanitizerArgs().needsAsanRt()) {
357 CmdArgs.push_back(Args.MakeArgString("-debug"));
358 CmdArgs.push_back(Args.MakeArgString("-incremental:no"));
359 if (TC.getSanitizerArgs().needsSharedAsanRt() ||
360 Args.hasArg(options::OPT__SLASH_MD, options::OPT__SLASH_MDd)) {
361 for (const auto &Lib : {"asan_dynamic", "asan_dynamic_runtime_thunk"})
362 CmdArgs.push_back(TC.getCompilerRTArgString(Args, Lib));
363 // Make sure the dynamic runtime thunk is not optimized out at link time
364 // to ensure proper SEH handling.
365 CmdArgs.push_back(Args.MakeArgString(
366 TC.getArch() == llvm::Triple::x86
367 ? "-include:___asan_seh_interceptor"
368 : "-include:__asan_seh_interceptor"));
369 // Make sure the linker consider all object files from the dynamic runtime
370 // thunk.
371 CmdArgs.push_back(Args.MakeArgString(std::string("-wholearchive:") +
372 TC.getCompilerRT(Args, "asan_dynamic_runtime_thunk")));
373 } else if (DLL) {
374 CmdArgs.push_back(TC.getCompilerRTArgString(Args, "asan_dll_thunk"));
375 } else {
376 for (const auto &Lib : {"asan", "asan_cxx"}) {
377 CmdArgs.push_back(TC.getCompilerRTArgString(Args, Lib));
378 // Make sure the linker consider all object files from the static lib.
379 // This is necessary because instrumented dlls need access to all the
380 // interface exported by the static lib in the main executable.
381 CmdArgs.push_back(Args.MakeArgString(std::string("-wholearchive:") +
382 TC.getCompilerRT(Args, Lib)));
383 }
384 }
385 }
386
387 Args.AddAllArgValues(CmdArgs, options::OPT__SLASH_link);
388
389 if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
390 options::OPT_fno_openmp, false)) {
391 CmdArgs.push_back("-nodefaultlib:vcomp.lib");
392 CmdArgs.push_back("-nodefaultlib:vcompd.lib");
393 CmdArgs.push_back(Args.MakeArgString(std::string("-libpath:") +
394 TC.getDriver().Dir + "/../lib"));
395 switch (TC.getDriver().getOpenMPRuntime(Args)) {
396 case Driver::OMPRT_OMP:
397 CmdArgs.push_back("-defaultlib:libomp.lib");
398 break;
399 case Driver::OMPRT_IOMP5:
400 CmdArgs.push_back("-defaultlib:libiomp5md.lib");
401 break;
402 case Driver::OMPRT_GOMP:
403 break;
404 case Driver::OMPRT_Unknown:
405 // Already diagnosed.
406 break;
407 }
408 }
409
410 // Add compiler-rt lib in case if it was explicitly
411 // specified as an argument for --rtlib option.
412 if (!Args.hasArg(options::OPT_nostdlib)) {
413 AddRunTimeLibs(TC, TC.getDriver(), CmdArgs, Args);
414 }
415
416 // Add filenames, libraries, and other linker inputs.
417 for (const auto &Input : Inputs) {
418 if (Input.isFilename()) {
419 CmdArgs.push_back(Input.getFilename());
420 continue;
421 }
422
423 const Arg &A = Input.getInputArg();
424
425 // Render -l options differently for the MSVC linker.
426 if (A.getOption().matches(options::OPT_l)) {
427 StringRef Lib = A.getValue();
428 const char *LinkLibArg;
429 if (Lib.endswith(".lib"))
430 LinkLibArg = Args.MakeArgString(Lib);
431 else
432 LinkLibArg = Args.MakeArgString(Lib + ".lib");
433 CmdArgs.push_back(LinkLibArg);
434 continue;
435 }
436
437 // Otherwise, this is some other kind of linker input option like -Wl, -z,
438 // or -L. Render it, even if MSVC doesn't understand it.
439 A.renderAsInput(Args, CmdArgs);
440 }
441
442 TC.addProfileRTLibs(Args, CmdArgs);
443
444 // We need to special case some linker paths. In the case of lld, we need to
445 // translate 'lld' into 'lld-link', and in the case of the regular msvc
446 // linker, we need to use a special search algorithm.
447 llvm::SmallString<128> linkPath;
448 StringRef Linker = Args.getLastArgValue(options::OPT_fuse_ld_EQ, "link");
449 if (Linker.equals_lower("lld"))
450 Linker = "lld-link";
451
452 if (Linker.equals_lower("link")) {
453 // If we're using the MSVC linker, it's not sufficient to just use link
454 // from the program PATH, because other environments like GnuWin32 install
455 // their own link.exe which may come first.
Zachary Turnerf6302522017-03-15 16:07:35 +0000456 linkPath = FindVisualStudioExecutable(TC, "link.exe");
David L. Jonesf561aba2017-03-08 01:02:16 +0000457 } else {
458 linkPath = Linker;
459 llvm::sys::path::replace_extension(linkPath, "exe");
460 linkPath = TC.GetProgramPath(linkPath.c_str());
461 }
462
463 const char *Exec = Args.MakeArgString(linkPath);
464 C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
465}
466
467void visualstudio::Compiler::ConstructJob(Compilation &C, const JobAction &JA,
468 const InputInfo &Output,
469 const InputInfoList &Inputs,
470 const ArgList &Args,
471 const char *LinkingOutput) const {
472 C.addCommand(GetCommand(C, JA, Output, Inputs, Args, LinkingOutput));
473}
474
475std::unique_ptr<Command> visualstudio::Compiler::GetCommand(
476 Compilation &C, const JobAction &JA, const InputInfo &Output,
477 const InputInfoList &Inputs, const ArgList &Args,
478 const char *LinkingOutput) const {
479 ArgStringList CmdArgs;
480 CmdArgs.push_back("/nologo");
481 CmdArgs.push_back("/c"); // Compile only.
482 CmdArgs.push_back("/W0"); // No warnings.
483
484 // The goal is to be able to invoke this tool correctly based on
485 // any flag accepted by clang-cl.
486
487 // These are spelled the same way in clang and cl.exe,.
488 Args.AddAllArgs(CmdArgs, {options::OPT_D, options::OPT_U, options::OPT_I});
489
490 // Optimization level.
491 if (Arg *A = Args.getLastArg(options::OPT_fbuiltin, options::OPT_fno_builtin))
492 CmdArgs.push_back(A->getOption().getID() == options::OPT_fbuiltin ? "/Oi"
493 : "/Oi-");
494 if (Arg *A = Args.getLastArg(options::OPT_O, options::OPT_O0)) {
495 if (A->getOption().getID() == options::OPT_O0) {
496 CmdArgs.push_back("/Od");
497 } else {
498 CmdArgs.push_back("/Og");
499
500 StringRef OptLevel = A->getValue();
501 if (OptLevel == "s" || OptLevel == "z")
502 CmdArgs.push_back("/Os");
503 else
504 CmdArgs.push_back("/Ot");
505
506 CmdArgs.push_back("/Ob2");
507 }
508 }
509 if (Arg *A = Args.getLastArg(options::OPT_fomit_frame_pointer,
510 options::OPT_fno_omit_frame_pointer))
511 CmdArgs.push_back(A->getOption().getID() == options::OPT_fomit_frame_pointer
512 ? "/Oy"
513 : "/Oy-");
514 if (!Args.hasArg(options::OPT_fwritable_strings))
515 CmdArgs.push_back("/GF");
516
517 // Flags for which clang-cl has an alias.
518 // FIXME: How can we ensure this stays in sync with relevant clang-cl options?
519
520 if (Args.hasFlag(options::OPT__SLASH_GR_, options::OPT__SLASH_GR,
521 /*default=*/false))
522 CmdArgs.push_back("/GR-");
523
524 if (Args.hasFlag(options::OPT__SLASH_GS_, options::OPT__SLASH_GS,
525 /*default=*/false))
526 CmdArgs.push_back("/GS-");
527
528 if (Arg *A = Args.getLastArg(options::OPT_ffunction_sections,
529 options::OPT_fno_function_sections))
530 CmdArgs.push_back(A->getOption().getID() == options::OPT_ffunction_sections
531 ? "/Gy"
532 : "/Gy-");
533 if (Arg *A = Args.getLastArg(options::OPT_fdata_sections,
534 options::OPT_fno_data_sections))
535 CmdArgs.push_back(
536 A->getOption().getID() == options::OPT_fdata_sections ? "/Gw" : "/Gw-");
537 if (Args.hasArg(options::OPT_fsyntax_only))
538 CmdArgs.push_back("/Zs");
539 if (Args.hasArg(options::OPT_g_Flag, options::OPT_gline_tables_only,
540 options::OPT__SLASH_Z7))
541 CmdArgs.push_back("/Z7");
542
543 std::vector<std::string> Includes =
544 Args.getAllArgValues(options::OPT_include);
545 for (const auto &Include : Includes)
546 CmdArgs.push_back(Args.MakeArgString(std::string("/FI") + Include));
547
548 // Flags that can simply be passed through.
549 Args.AddAllArgs(CmdArgs, options::OPT__SLASH_LD);
550 Args.AddAllArgs(CmdArgs, options::OPT__SLASH_LDd);
551 Args.AddAllArgs(CmdArgs, options::OPT__SLASH_GX);
552 Args.AddAllArgs(CmdArgs, options::OPT__SLASH_GX_);
553 Args.AddAllArgs(CmdArgs, options::OPT__SLASH_EH);
554 Args.AddAllArgs(CmdArgs, options::OPT__SLASH_Zl);
555
556 // The order of these flags is relevant, so pick the last one.
557 if (Arg *A = Args.getLastArg(options::OPT__SLASH_MD, options::OPT__SLASH_MDd,
558 options::OPT__SLASH_MT, options::OPT__SLASH_MTd))
559 A->render(Args, CmdArgs);
560
561 // Use MSVC's default threadsafe statics behaviour unless there was a flag.
562 if (Arg *A = Args.getLastArg(options::OPT_fthreadsafe_statics,
563 options::OPT_fno_threadsafe_statics)) {
564 CmdArgs.push_back(A->getOption().getID() == options::OPT_fthreadsafe_statics
565 ? "/Zc:threadSafeInit"
566 : "/Zc:threadSafeInit-");
567 }
568
569 // Pass through all unknown arguments so that the fallback command can see
570 // them too.
571 Args.AddAllArgs(CmdArgs, options::OPT_UNKNOWN);
572
573 // Input filename.
574 assert(Inputs.size() == 1);
575 const InputInfo &II = Inputs[0];
576 assert(II.getType() == types::TY_C || II.getType() == types::TY_CXX);
577 CmdArgs.push_back(II.getType() == types::TY_C ? "/Tc" : "/Tp");
578 if (II.isFilename())
579 CmdArgs.push_back(II.getFilename());
580 else
581 II.getInputArg().renderAsInput(Args, CmdArgs);
582
583 // Output filename.
584 assert(Output.getType() == types::TY_Object);
585 const char *Fo =
586 Args.MakeArgString(std::string("/Fo") + Output.getFilename());
587 CmdArgs.push_back(Fo);
588
Zachary Turnerf6302522017-03-15 16:07:35 +0000589 std::string Exec = FindVisualStudioExecutable(getToolChain(), "cl.exe");
David L. Jonesf561aba2017-03-08 01:02:16 +0000590 return llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Exec),
591 CmdArgs, Inputs);
592}
593
Reid Klecknerbf183552017-02-02 19:36:22 +0000594MSVCToolChain::MSVCToolChain(const Driver &D, const llvm::Triple &Triple,
Saleem Abdulrasool819f3912014-10-22 02:37:29 +0000595 const ArgList &Args)
Justin Lebar58891902017-01-05 16:52:29 +0000596 : ToolChain(D, Triple, Args), CudaInstallation(D, Triple, Args) {
Zachary Turner719f58c2014-12-01 23:06:47 +0000597 getProgramPaths().push_back(getDriver().getInstalledDir());
598 if (getDriver().getInstalledDir() != getDriver().Dir)
599 getProgramPaths().push_back(getDriver().Dir);
Zachary Turnerf6302522017-03-15 16:07:35 +0000600
601 // Check the environment first, since that's probably the user telling us
602 // what they want to use.
603 // Failing that, just try to find the newest Visual Studio version we can
604 // and use its default VC toolchain.
605 findVCToolChainViaEnvironment(VCToolChainPath, IsVS2017OrNewer) ||
606 findVCToolChainViaSetupConfig(VCToolChainPath, IsVS2017OrNewer) ||
607 findVCToolChainViaRegistry(VCToolChainPath, IsVS2017OrNewer);
Hans Wennborg1cc6cce2013-08-30 09:42:06 +0000608}
609
Saleem Abdulrasool819f3912014-10-22 02:37:29 +0000610Tool *MSVCToolChain::buildLinker() const {
Zachary Turnerf6302522017-03-15 16:07:35 +0000611 if (VCToolChainPath.empty())
612 getDriver().Diag(clang::diag::warn_drv_msvc_not_found);
Douglas Katzman95354292015-06-23 20:42:09 +0000613 return new tools::visualstudio::Linker(*this);
Hans Wennborg1cc6cce2013-08-30 09:42:06 +0000614}
615
Saleem Abdulrasool819f3912014-10-22 02:37:29 +0000616Tool *MSVCToolChain::buildAssembler() const {
Saleem Abdulrasool377066a2014-03-27 22:50:18 +0000617 if (getTriple().isOSBinFormatMachO())
Douglas Katzman95354292015-06-23 20:42:09 +0000618 return new tools::darwin::Assembler(*this);
Alp Tokerc8d4f0f2013-11-22 08:27:46 +0000619 getDriver().Diag(clang::diag::err_no_external_assembler);
Craig Topper92fc2df2014-05-17 16:56:41 +0000620 return nullptr;
Hans Wennborg1cc6cce2013-08-30 09:42:06 +0000621}
622
Saleem Abdulrasool819f3912014-10-22 02:37:29 +0000623bool MSVCToolChain::IsIntegratedAssemblerDefault() const {
Hans Wennborg1cc6cce2013-08-30 09:42:06 +0000624 return true;
625}
626
Saleem Abdulrasool819f3912014-10-22 02:37:29 +0000627bool MSVCToolChain::IsUnwindTablesDefault() const {
Reid Kleckner6b3a9402014-09-04 18:13:12 +0000628 // Emit unwind tables by default on Win64. All non-x86_32 Windows platforms
629 // such as ARM and PPC actually require unwind tables, but LLVM doesn't know
630 // how to generate them yet.
Akira Hatanakae4218132016-05-05 01:41:07 +0000631
632 // Don't emit unwind tables by default for MachO targets.
633 if (getTriple().isOSBinFormatMachO())
634 return false;
635
Reid Kleckner6b3a9402014-09-04 18:13:12 +0000636 return getArch() == llvm::Triple::x86_64;
Hans Wennborg1cc6cce2013-08-30 09:42:06 +0000637}
638
Reid Kleckner8c190832016-12-28 17:41:36 +0000639bool MSVCToolChain::isPICDefault() const {
640 return getArch() == llvm::Triple::x86_64;
641}
642
643bool MSVCToolChain::isPIEDefault() const {
644 return false;
645}
646
647bool MSVCToolChain::isPICDefaultForced() const {
648 return getArch() == llvm::Triple::x86_64;
649}
650
Justin Lebar58891902017-01-05 16:52:29 +0000651void MSVCToolChain::AddCudaIncludeArgs(const ArgList &DriverArgs,
652 ArgStringList &CC1Args) const {
653 CudaInstallation.AddCudaIncludeArgs(DriverArgs, CC1Args);
654}
655
656void MSVCToolChain::printVerboseInfo(raw_ostream &OS) const {
657 CudaInstallation.print(OS);
658}
659
Zachary Turnerf6302522017-03-15 16:07:35 +0000660// Windows SDKs and VC Toolchains group their contents into subdirectories based
661// on the target architecture. This function converts an llvm::Triple::ArchType
662// to the corresponding subdirectory name.
663static const char *llvmArchToWindowsSDKArch(llvm::Triple::ArchType Arch) {
664 using ArchType = llvm::Triple::ArchType;
665 switch (Arch) {
666 case ArchType::x86:
667 return "x86";
668 case ArchType::x86_64:
669 return "x64";
670 case ArchType::arm:
671 return "arm";
672 default:
673 return "";
674 }
675}
676
677// Similar to the above function, but for Visual Studios before VS2017.
678static const char *llvmArchToLegacyVCArch(llvm::Triple::ArchType Arch) {
679 using ArchType = llvm::Triple::ArchType;
680 switch (Arch) {
681 case ArchType::x86:
682 // x86 is default in legacy VC toolchains.
683 // e.g. x86 libs are directly in /lib as opposed to /lib/x86.
684 return "";
685 case ArchType::x86_64:
686 return "amd64";
687 case ArchType::arm:
688 return "arm";
689 default:
690 return "";
691 }
692}
693
694// Get the path to a specific subdirectory in the current toolchain for
695// a given target architecture.
696// VS2017 changed the VC toolchain layout, so this should be used instead
697// of hardcoding paths.
698std::string
699MSVCToolChain::getSubDirectoryPath(SubDirectoryType Type,
700 llvm::Triple::ArchType TargetArch) const {
701 llvm::SmallString<256> Path(VCToolChainPath);
702 switch (Type) {
703 case SubDirectoryType::Bin:
704 if (IsVS2017OrNewer) {
705 bool HostIsX64 =
706 llvm::Triple(llvm::sys::getProcessTriple()).isArch64Bit();
707 llvm::sys::path::append(Path, "bin", (HostIsX64 ? "HostX64" : "HostX86"),
708 llvmArchToWindowsSDKArch(TargetArch));
709
710 } else {
711 llvm::sys::path::append(Path, "bin", llvmArchToLegacyVCArch(TargetArch));
712 }
713 break;
714 case SubDirectoryType::Include:
715 llvm::sys::path::append(Path, "include");
716 break;
717 case SubDirectoryType::Lib:
718 llvm::sys::path::append(
719 Path, "lib", IsVS2017OrNewer ? llvmArchToWindowsSDKArch(TargetArch)
720 : llvmArchToLegacyVCArch(TargetArch));
721 break;
722 }
723 return Path.str();
724}
725
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000726#ifdef USE_WIN32
727static bool readFullStringValue(HKEY hkey, const char *valueName,
728 std::string &value) {
Aaron Ballmanb06a3592016-06-23 14:33:53 +0000729 std::wstring WideValueName;
730 if (!llvm::ConvertUTF8toWide(valueName, WideValueName))
731 return false;
732
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000733 DWORD result = 0;
734 DWORD valueSize = 0;
735 DWORD type = 0;
736 // First just query for the required size.
Aaron Ballmanb06a3592016-06-23 14:33:53 +0000737 result = RegQueryValueExW(hkey, WideValueName.c_str(), NULL, &type, NULL,
738 &valueSize);
739 if (result != ERROR_SUCCESS || type != REG_SZ || !valueSize)
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000740 return false;
741 std::vector<BYTE> buffer(valueSize);
Aaron Ballmanb06a3592016-06-23 14:33:53 +0000742 result = RegQueryValueExW(hkey, WideValueName.c_str(), NULL, NULL, &buffer[0],
743 &valueSize);
744 if (result == ERROR_SUCCESS) {
745 std::wstring WideValue(reinterpret_cast<const wchar_t *>(buffer.data()),
746 valueSize / sizeof(wchar_t));
Zachary Turnere78a3472016-07-28 17:13:32 +0000747 if (valueSize && WideValue.back() == L'\0') {
Etienne Bergeron982a3bc2016-08-30 18:38:25 +0000748 WideValue.pop_back();
Zachary Turnere78a3472016-07-28 17:13:32 +0000749 }
Aaron Ballmanb06a3592016-06-23 14:33:53 +0000750 // The destination buffer must be empty as an invariant of the conversion
751 // function; but this function is sometimes called in a loop that passes in
752 // the same buffer, however. Simply clear it out so we can overwrite it.
753 value.clear();
754 return llvm::convertWideToUTF8(WideValue, value);
755 }
756 return false;
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000757}
758#endif
759
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000760/// \brief Read registry string.
761/// This also supports a means to look for high-versioned keys by use
762/// of a $VERSION placeholder in the key path.
763/// $VERSION in the key path is a placeholder for the version number,
764/// causing the highest value path to be searched for and used.
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000765/// I.e. "SOFTWARE\\Microsoft\\VisualStudio\\$VERSION".
766/// There can be additional characters in the component. Only the numeric
767/// characters are compared. This function only searches HKLM.
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000768static bool getSystemRegistryString(const char *keyPath, const char *valueName,
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000769 std::string &value, std::string *phValue) {
Alp Tokerfcce1832014-06-22 03:27:45 +0000770#ifndef USE_WIN32
771 return false;
772#else
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000773 HKEY hRootKey = HKEY_LOCAL_MACHINE;
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000774 HKEY hKey = NULL;
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000775 long lResult;
776 bool returnValue = false;
777
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000778 const char *placeHolder = strstr(keyPath, "$VERSION");
779 std::string bestName;
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000780 // If we have a $VERSION placeholder, do the highest-version search.
781 if (placeHolder) {
782 const char *keyEnd = placeHolder - 1;
783 const char *nextKey = placeHolder;
784 // Find end of previous key.
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000785 while ((keyEnd > keyPath) && (*keyEnd != '\\'))
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000786 keyEnd--;
787 // Find end of key containing $VERSION.
788 while (*nextKey && (*nextKey != '\\'))
789 nextKey++;
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000790 size_t partialKeyLength = keyEnd - keyPath;
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000791 char partialKey[256];
Daniel Marjamakie1146692016-01-27 07:33:50 +0000792 if (partialKeyLength >= sizeof(partialKey))
793 partialKeyLength = sizeof(partialKey) - 1;
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000794 strncpy(partialKey, keyPath, partialKeyLength);
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000795 partialKey[partialKeyLength] = '\0';
796 HKEY hTopKey = NULL;
Aaron Ballmanb06a3592016-06-23 14:33:53 +0000797 lResult = RegOpenKeyExA(hRootKey, partialKey, 0, KEY_READ | KEY_WOW64_32KEY,
798 &hTopKey);
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000799 if (lResult == ERROR_SUCCESS) {
800 char keyName[256];
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000801 double bestValue = 0.0;
802 DWORD index, size = sizeof(keyName) - 1;
Aaron Ballmanb06a3592016-06-23 14:33:53 +0000803 for (index = 0; RegEnumKeyExA(hTopKey, index, keyName, &size, NULL, NULL,
804 NULL, NULL) == ERROR_SUCCESS;
805 index++) {
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000806 const char *sp = keyName;
Jordan Rosea7d03842013-02-08 22:30:41 +0000807 while (*sp && !isDigit(*sp))
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000808 sp++;
809 if (!*sp)
810 continue;
811 const char *ep = sp + 1;
Jordan Rosea7d03842013-02-08 22:30:41 +0000812 while (*ep && (isDigit(*ep) || (*ep == '.')))
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000813 ep++;
814 char numBuf[32];
815 strncpy(numBuf, sp, sizeof(numBuf) - 1);
816 numBuf[sizeof(numBuf) - 1] = '\0';
Hans Wennborgd2192312013-10-10 18:03:08 +0000817 double dvalue = strtod(numBuf, NULL);
818 if (dvalue > bestValue) {
819 // Test that InstallDir is indeed there before keeping this index.
820 // Open the chosen key path remainder.
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000821 bestName = keyName;
Hans Wennborgd2192312013-10-10 18:03:08 +0000822 // Append rest of key.
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000823 bestName.append(nextKey);
Aaron Ballmanb06a3592016-06-23 14:33:53 +0000824 lResult = RegOpenKeyExA(hTopKey, bestName.c_str(), 0,
825 KEY_READ | KEY_WOW64_32KEY, &hKey);
Hans Wennborgd2192312013-10-10 18:03:08 +0000826 if (lResult == ERROR_SUCCESS) {
Zachary Turnere78a3472016-07-28 17:13:32 +0000827 if (readFullStringValue(hKey, valueName, value)) {
Hans Wennborgd2192312013-10-10 18:03:08 +0000828 bestValue = dvalue;
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000829 if (phValue)
830 *phValue = bestName;
Hans Wennborgd2192312013-10-10 18:03:08 +0000831 returnValue = true;
832 }
833 RegCloseKey(hKey);
834 }
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000835 }
836 size = sizeof(keyName) - 1;
837 }
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000838 RegCloseKey(hTopKey);
839 }
840 } else {
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000841 lResult =
Aaron Ballmanb06a3592016-06-23 14:33:53 +0000842 RegOpenKeyExA(hRootKey, keyPath, 0, KEY_READ | KEY_WOW64_32KEY, &hKey);
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000843 if (lResult == ERROR_SUCCESS) {
Zachary Turnere78a3472016-07-28 17:13:32 +0000844 if (readFullStringValue(hKey, valueName, value))
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000845 returnValue = true;
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000846 if (phValue)
847 phValue->clear();
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000848 RegCloseKey(hKey);
849 }
850 }
851 return returnValue;
Alp Tokerfcce1832014-06-22 03:27:45 +0000852#endif // USE_WIN32
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000853}
854
Igor Kudrinf2e75242015-09-24 05:16:36 +0000855// Find the most recent version of Universal CRT or Windows 10 SDK.
856// vcvarsqueryregistry.bat from Visual Studio 2015 sorts entries in the include
857// directory by name and uses the last one of the list.
858// So we compare entry names lexicographically to find the greatest one.
Zachary Turnerf6302522017-03-15 16:07:35 +0000859static bool getWindows10SDKVersionFromPath(const std::string &SDKPath,
860 std::string &SDKVersion) {
Igor Kudrinf2e75242015-09-24 05:16:36 +0000861 SDKVersion.clear();
862
863 std::error_code EC;
864 llvm::SmallString<128> IncludePath(SDKPath);
865 llvm::sys::path::append(IncludePath, "Include");
866 for (llvm::sys::fs::directory_iterator DirIt(IncludePath, EC), DirEnd;
867 DirIt != DirEnd && !EC; DirIt.increment(EC)) {
868 if (!llvm::sys::fs::is_directory(DirIt->path()))
869 continue;
870 StringRef CandidateName = llvm::sys::path::filename(DirIt->path());
871 // If WDK is installed, there could be subfolders like "wdf" in the
872 // "Include" directory.
873 // Allow only directories which names start with "10.".
874 if (!CandidateName.startswith("10."))
875 continue;
876 if (CandidateName > SDKVersion)
877 SDKVersion = CandidateName;
878 }
879
880 return !SDKVersion.empty();
881}
882
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000883/// \brief Get Windows SDK installation directory.
Zachary Turnerf6302522017-03-15 16:07:35 +0000884static bool getWindowsSDKDir(std::string &Path, int &Major,
885 std::string &WindowsSDKIncludeVersion,
886 std::string &WindowsSDKLibVersion) {
Igor Kudrinf2e75242015-09-24 05:16:36 +0000887 std::string RegistrySDKVersion;
Chandler Carruth1fc603e2011-12-17 23:10:01 +0000888 // Try the Windows registry.
Igor Kudrinf2e75242015-09-24 05:16:36 +0000889 if (!getSystemRegistryString(
890 "SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\$VERSION",
891 "InstallationFolder", Path, &RegistrySDKVersion))
892 return false;
893 if (Path.empty() || RegistrySDKVersion.empty())
894 return false;
895
896 WindowsSDKIncludeVersion.clear();
897 WindowsSDKLibVersion.clear();
898 Major = 0;
899 std::sscanf(RegistrySDKVersion.c_str(), "v%d.", &Major);
900 if (Major <= 7)
901 return true;
902 if (Major == 8) {
903 // Windows SDK 8.x installs libraries in a folder whose names depend on the
904 // version of the OS you're targeting. By default choose the newest, which
905 // usually corresponds to the version of the OS you've installed the SDK on.
906 const char *Tests[] = {"winv6.3", "win8", "win7"};
907 for (const char *Test : Tests) {
908 llvm::SmallString<128> TestPath(Path);
909 llvm::sys::path::append(TestPath, "Lib", Test);
910 if (llvm::sys::fs::exists(TestPath.c_str())) {
911 WindowsSDKLibVersion = Test;
912 break;
913 }
914 }
915 return !WindowsSDKLibVersion.empty();
916 }
917 if (Major == 10) {
Zachary Turnerf6302522017-03-15 16:07:35 +0000918 if (!getWindows10SDKVersionFromPath(Path, WindowsSDKIncludeVersion))
Igor Kudrinf2e75242015-09-24 05:16:36 +0000919 return false;
920 WindowsSDKLibVersion = WindowsSDKIncludeVersion;
921 return true;
922 }
923 // Unsupported SDK version
924 return false;
Zachary Turner0eaf8fc2014-10-22 20:40:28 +0000925}
926
Zachary Turner10d75b22014-10-22 20:40:43 +0000927// Gets the library path required to link against the Windows SDK.
928bool MSVCToolChain::getWindowsSDKLibraryPath(std::string &path) const {
929 std::string sdkPath;
930 int sdkMajor = 0;
Igor Kudrinf2e75242015-09-24 05:16:36 +0000931 std::string windowsSDKIncludeVersion;
932 std::string windowsSDKLibVersion;
Zachary Turner10d75b22014-10-22 20:40:43 +0000933
934 path.clear();
Igor Kudrinf2e75242015-09-24 05:16:36 +0000935 if (!getWindowsSDKDir(sdkPath, sdkMajor, windowsSDKIncludeVersion,
936 windowsSDKLibVersion))
Zachary Turner10d75b22014-10-22 20:40:43 +0000937 return false;
938
939 llvm::SmallString<128> libPath(sdkPath);
940 llvm::sys::path::append(libPath, "Lib");
Zachary Turnerf6302522017-03-15 16:07:35 +0000941 if (sdkMajor >= 8) {
942 llvm::sys::path::append(libPath, windowsSDKLibVersion, "um",
943 llvmArchToWindowsSDKArch(getArch()));
944 } else {
Zachary Turner10d75b22014-10-22 20:40:43 +0000945 switch (getArch()) {
Reid Klecknerbf183552017-02-02 19:36:22 +0000946 // In Windows SDK 7.x, x86 libraries are directly in the Lib folder.
Zachary Turner10d75b22014-10-22 20:40:43 +0000947 case llvm::Triple::x86:
948 break;
949 case llvm::Triple::x86_64:
950 llvm::sys::path::append(libPath, "x64");
951 break;
952 case llvm::Triple::arm:
953 // It is not necessary to link against Windows SDK 7.x when targeting ARM.
954 return false;
955 default:
956 return false;
957 }
Zachary Turner10d75b22014-10-22 20:40:43 +0000958 }
959
960 path = libPath.str();
961 return true;
962}
963
Reid Kleckner7531f7d2015-09-11 00:09:39 +0000964// Check if the Include path of a specified version of Visual Studio contains
965// specific header files. If not, they are probably shipped with Universal CRT.
Zachary Turnerf6302522017-03-15 16:07:35 +0000966bool MSVCToolChain::useUniversalCRT() const {
967 llvm::SmallString<128> TestPath(
968 getSubDirectoryPath(SubDirectoryType::Include));
969 llvm::sys::path::append(TestPath, "stdlib.h");
Reid Kleckner7531f7d2015-09-11 00:09:39 +0000970 return !llvm::sys::fs::exists(TestPath);
971}
972
Zachary Turnerf6302522017-03-15 16:07:35 +0000973static bool getUniversalCRTSdkDir(std::string &Path, std::string &UCRTVersion) {
Reid Kleckner7531f7d2015-09-11 00:09:39 +0000974 // vcvarsqueryregistry.bat for Visual Studio 2015 queries the registry
975 // for the specific key "KitsRoot10". So do we.
976 if (!getSystemRegistryString(
Reid Klecknerbf183552017-02-02 19:36:22 +0000977 "SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots", "KitsRoot10",
978 Path, nullptr))
Reid Kleckner7531f7d2015-09-11 00:09:39 +0000979 return false;
980
Zachary Turnerf6302522017-03-15 16:07:35 +0000981 return getWindows10SDKVersionFromPath(Path, UCRTVersion);
Reid Kleckner7531f7d2015-09-11 00:09:39 +0000982}
983
984bool MSVCToolChain::getUniversalCRTLibraryPath(std::string &Path) const {
985 std::string UniversalCRTSdkPath;
986 std::string UCRTVersion;
987
988 Path.clear();
989 if (!getUniversalCRTSdkDir(UniversalCRTSdkPath, UCRTVersion))
990 return false;
991
Zachary Turnerf6302522017-03-15 16:07:35 +0000992 StringRef ArchName = llvmArchToWindowsSDKArch(getArch());
Reid Kleckner7531f7d2015-09-11 00:09:39 +0000993 if (ArchName.empty())
994 return false;
995
996 llvm::SmallString<128> LibPath(UniversalCRTSdkPath);
997 llvm::sys::path::append(LibPath, "Lib", UCRTVersion, "ucrt", ArchName);
998
999 Path = LibPath.str();
1000 return true;
1001}
1002
Zachary Turnerf6302522017-03-15 16:07:35 +00001003static VersionTuple getMSVCVersionFromTriple(const llvm::Triple &Triple) {
David L. Jones24fb20c2016-12-07 23:41:58 +00001004 unsigned Major, Minor, Micro;
Zachary Turnerf6302522017-03-15 16:07:35 +00001005 Triple.getEnvironmentVersion(Major, Minor, Micro);
David L. Jones24fb20c2016-12-07 23:41:58 +00001006 if (Major || Minor || Micro)
1007 return VersionTuple(Major, Minor, Micro);
1008 return VersionTuple();
1009}
1010
Zachary Turnerf6302522017-03-15 16:07:35 +00001011static VersionTuple getMSVCVersionFromExe(const std::string &BinDir) {
Adrian McCarthye4b26fc2016-05-13 23:20:11 +00001012 VersionTuple Version;
1013#ifdef USE_WIN32
Zachary Turnerf6302522017-03-15 16:07:35 +00001014 SmallString<128> ClExe(BinDir);
Adrian McCarthye4b26fc2016-05-13 23:20:11 +00001015 llvm::sys::path::append(ClExe, "cl.exe");
1016
1017 std::wstring ClExeWide;
1018 if (!llvm::ConvertUTF8toWide(ClExe.c_str(), ClExeWide))
1019 return Version;
1020
1021 const DWORD VersionSize = ::GetFileVersionInfoSizeW(ClExeWide.c_str(),
1022 nullptr);
1023 if (VersionSize == 0)
1024 return Version;
1025
1026 SmallVector<uint8_t, 4 * 1024> VersionBlock(VersionSize);
1027 if (!::GetFileVersionInfoW(ClExeWide.c_str(), 0, VersionSize,
1028 VersionBlock.data()))
1029 return Version;
1030
1031 VS_FIXEDFILEINFO *FileInfo = nullptr;
1032 UINT FileInfoSize = 0;
1033 if (!::VerQueryValueW(VersionBlock.data(), L"\\",
1034 reinterpret_cast<LPVOID *>(&FileInfo), &FileInfoSize) ||
1035 FileInfoSize < sizeof(*FileInfo))
1036 return Version;
1037
1038 const unsigned Major = (FileInfo->dwFileVersionMS >> 16) & 0xFFFF;
1039 const unsigned Minor = (FileInfo->dwFileVersionMS ) & 0xFFFF;
1040 const unsigned Micro = (FileInfo->dwFileVersionLS >> 16) & 0xFFFF;
1041
1042 Version = VersionTuple(Major, Minor, Micro);
1043#endif
1044 return Version;
1045}
1046
Igor Kudrinf2e75242015-09-24 05:16:36 +00001047void MSVCToolChain::AddSystemIncludeWithSubfolder(
1048 const ArgList &DriverArgs, ArgStringList &CC1Args,
1049 const std::string &folder, const Twine &subfolder1, const Twine &subfolder2,
1050 const Twine &subfolder3) const {
Zachary Turner0eaf8fc2014-10-22 20:40:28 +00001051 llvm::SmallString<128> path(folder);
Igor Kudrinf2e75242015-09-24 05:16:36 +00001052 llvm::sys::path::append(path, subfolder1, subfolder2, subfolder3);
Yaron Keren92e1b622015-03-18 10:17:07 +00001053 addSystemInclude(DriverArgs, CC1Args, path);
Zachary Turner0eaf8fc2014-10-22 20:40:28 +00001054}
1055
Saleem Abdulrasool819f3912014-10-22 02:37:29 +00001056void MSVCToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
1057 ArgStringList &CC1Args) const {
Chandler Carruth1fc603e2011-12-17 23:10:01 +00001058 if (DriverArgs.hasArg(options::OPT_nostdinc))
1059 return;
1060
1061 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
Igor Kudrinf2e75242015-09-24 05:16:36 +00001062 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, getDriver().ResourceDir,
1063 "include");
Chandler Carruth1fc603e2011-12-17 23:10:01 +00001064 }
1065
Nico Weberfd3e1ad2016-04-12 19:04:37 +00001066 // Add %INCLUDE%-like directories from the -imsvc flag.
1067 for (const auto &Path : DriverArgs.getAllArgValues(options::OPT__SLASH_imsvc))
1068 addSystemInclude(DriverArgs, CC1Args, Path);
1069
Chandler Carruth1fc603e2011-12-17 23:10:01 +00001070 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
1071 return;
1072
Joao Matos792d7af2012-09-04 17:29:52 +00001073 // Honor %INCLUDE%. It should know essential search paths with vcvarsall.bat.
David Majnemer85c25b42016-07-24 17:44:03 +00001074 if (llvm::Optional<std::string> cl_include_dir =
1075 llvm::sys::Process::GetEnv("INCLUDE")) {
Joao Matos792d7af2012-09-04 17:29:52 +00001076 SmallVector<StringRef, 8> Dirs;
David Majnemer85c25b42016-07-24 17:44:03 +00001077 StringRef(*cl_include_dir)
Reid Kleckner77b45ba2014-04-23 00:15:01 +00001078 .split(Dirs, ";", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
1079 for (StringRef Dir : Dirs)
1080 addSystemInclude(DriverArgs, CC1Args, Dir);
1081 if (!Dirs.empty())
1082 return;
Joao Matos792d7af2012-09-04 17:29:52 +00001083 }
1084
Joao Matos792d7af2012-09-04 17:29:52 +00001085 // When built with access to the proper Windows APIs, try to actually find
1086 // the correct include paths first.
Zachary Turnerf6302522017-03-15 16:07:35 +00001087 if (!VCToolChainPath.empty()) {
1088 addSystemInclude(DriverArgs, CC1Args,
1089 getSubDirectoryPath(SubDirectoryType::Include));
Zachary Turner0eaf8fc2014-10-22 20:40:28 +00001090
Zachary Turnerf6302522017-03-15 16:07:35 +00001091 if (useUniversalCRT()) {
Reid Kleckner7531f7d2015-09-11 00:09:39 +00001092 std::string UniversalCRTSdkPath;
1093 std::string UCRTVersion;
1094 if (getUniversalCRTSdkDir(UniversalCRTSdkPath, UCRTVersion)) {
Igor Kudrinf2e75242015-09-24 05:16:36 +00001095 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, UniversalCRTSdkPath,
1096 "Include", UCRTVersion, "ucrt");
Reid Kleckner7531f7d2015-09-11 00:09:39 +00001097 }
1098 }
1099
Zachary Turner0eaf8fc2014-10-22 20:40:28 +00001100 std::string WindowsSDKDir;
Igor Kudrinf2e75242015-09-24 05:16:36 +00001101 int major;
1102 std::string windowsSDKIncludeVersion;
1103 std::string windowsSDKLibVersion;
1104 if (getWindowsSDKDir(WindowsSDKDir, major, windowsSDKIncludeVersion,
1105 windowsSDKLibVersion)) {
Zachary Turner0eaf8fc2014-10-22 20:40:28 +00001106 if (major >= 8) {
Igor Kudrinf2e75242015-09-24 05:16:36 +00001107 // Note: windowsSDKIncludeVersion is empty for SDKs prior to v10.
1108 // Anyway, llvm::sys::path::append is able to manage it.
Zachary Turner0eaf8fc2014-10-22 20:40:28 +00001109 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
Igor Kudrinf2e75242015-09-24 05:16:36 +00001110 "include", windowsSDKIncludeVersion,
1111 "shared");
Zachary Turner0eaf8fc2014-10-22 20:40:28 +00001112 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
Igor Kudrinf2e75242015-09-24 05:16:36 +00001113 "include", windowsSDKIncludeVersion,
1114 "um");
Zachary Turner0eaf8fc2014-10-22 20:40:28 +00001115 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
Igor Kudrinf2e75242015-09-24 05:16:36 +00001116 "include", windowsSDKIncludeVersion,
1117 "winrt");
Zachary Turner0eaf8fc2014-10-22 20:40:28 +00001118 } else {
1119 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
1120 "include");
1121 }
Reid Kleckner77b45ba2014-04-23 00:15:01 +00001122 }
Zachary Turnerf6302522017-03-15 16:07:35 +00001123
Joao Matos792d7af2012-09-04 17:29:52 +00001124 return;
1125 }
Joao Matos792d7af2012-09-04 17:29:52 +00001126
David Majnemerd5f7d192016-07-25 04:47:44 +00001127#if defined(LLVM_ON_WIN32)
Joao Matos792d7af2012-09-04 17:29:52 +00001128 // As a fallback, select default install paths.
Alp Tokerfcce1832014-06-22 03:27:45 +00001129 // FIXME: Don't guess drives and paths like this on Windows.
Joao Matos792d7af2012-09-04 17:29:52 +00001130 const StringRef Paths[] = {
1131 "C:/Program Files/Microsoft Visual Studio 10.0/VC/include",
1132 "C:/Program Files/Microsoft Visual Studio 9.0/VC/include",
1133 "C:/Program Files/Microsoft Visual Studio 9.0/VC/PlatformSDK/Include",
1134 "C:/Program Files/Microsoft Visual Studio 8/VC/include",
1135 "C:/Program Files/Microsoft Visual Studio 8/VC/PlatformSDK/Include"
1136 };
1137 addSystemIncludes(DriverArgs, CC1Args, Paths);
David Majnemerd5f7d192016-07-25 04:47:44 +00001138#endif
Chandler Carruth1fc603e2011-12-17 23:10:01 +00001139}
1140
Saleem Abdulrasool819f3912014-10-22 02:37:29 +00001141void MSVCToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
1142 ArgStringList &CC1Args) const {
Chandler Carruth1fc603e2011-12-17 23:10:01 +00001143 // FIXME: There should probably be logic here to find libc++ on Windows.
1144}
David Majnemere11d3732015-06-08 00:22:46 +00001145
David L. Jones24fb20c2016-12-07 23:41:58 +00001146VersionTuple MSVCToolChain::computeMSVCVersion(const Driver *D,
1147 const ArgList &Args) const {
1148 bool IsWindowsMSVC = getTriple().isWindowsMSVCEnvironment();
1149 VersionTuple MSVT = ToolChain::computeMSVCVersion(D, Args);
Zachary Turnerf6302522017-03-15 16:07:35 +00001150 if (MSVT.empty())
1151 MSVT = getMSVCVersionFromTriple(getTriple());
1152 if (MSVT.empty() && IsWindowsMSVC)
1153 MSVT = getMSVCVersionFromExe(getSubDirectoryPath(SubDirectoryType::Bin));
David L. Jones24fb20c2016-12-07 23:41:58 +00001154 if (MSVT.empty() &&
1155 Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions,
1156 IsWindowsMSVC)) {
1157 // -fms-compatibility-version=18.00 is default.
1158 // FIXME: Consider bumping this to 19 (MSVC2015) soon.
1159 MSVT = VersionTuple(18);
1160 }
1161 return MSVT;
1162}
1163
David Majnemere11d3732015-06-08 00:22:46 +00001164std::string
1165MSVCToolChain::ComputeEffectiveClangTriple(const ArgList &Args,
1166 types::ID InputType) const {
David L. Jones24fb20c2016-12-07 23:41:58 +00001167 // The MSVC version doesn't care about the architecture, even though it
1168 // may look at the triple internally.
1169 VersionTuple MSVT = computeMSVCVersion(/*D=*/nullptr, Args);
David Majnemere11d3732015-06-08 00:22:46 +00001170 MSVT = VersionTuple(MSVT.getMajor(), MSVT.getMinor().getValueOr(0),
1171 MSVT.getSubminor().getValueOr(0));
1172
David L. Jones24fb20c2016-12-07 23:41:58 +00001173 // For the rest of the triple, however, a computed architecture name may
1174 // be needed.
1175 llvm::Triple Triple(ToolChain::ComputeEffectiveClangTriple(Args, InputType));
David Majnemer75fdd6b2015-06-09 06:30:01 +00001176 if (Triple.getEnvironment() == llvm::Triple::MSVC) {
1177 StringRef ObjFmt = Triple.getEnvironmentName().split('-').second;
1178 if (ObjFmt.empty())
1179 Triple.setEnvironmentName((Twine("msvc") + MSVT.getAsString()).str());
1180 else
1181 Triple.setEnvironmentName(
1182 (Twine("msvc") + MSVT.getAsString() + Twine('-') + ObjFmt).str());
1183 }
David Majnemere11d3732015-06-08 00:22:46 +00001184 return Triple.getTriple();
1185}
Alexey Samsonov7f2a0d22015-06-19 21:36:47 +00001186
1187SanitizerMask MSVCToolChain::getSupportedSanitizers() const {
1188 SanitizerMask Res = ToolChain::getSupportedSanitizers();
1189 Res |= SanitizerKind::Address;
Alexey Samsonov7f2a0d22015-06-19 21:36:47 +00001190 return Res;
1191}
David Majnemer015ce0f2015-07-27 07:32:11 +00001192
Hans Wennborg21d73d22016-01-12 23:17:03 +00001193static void TranslateOptArg(Arg *A, llvm::opt::DerivedArgList &DAL,
1194 bool SupportsForcingFramePointer,
1195 const char *ExpandChar, const OptTable &Opts) {
1196 assert(A->getOption().matches(options::OPT__SLASH_O));
1197
1198 StringRef OptStr = A->getValue();
1199 for (size_t I = 0, E = OptStr.size(); I != E; ++I) {
1200 const char &OptChar = *(OptStr.data() + I);
1201 switch (OptChar) {
1202 default:
1203 break;
1204 case '1':
1205 case '2':
1206 case 'x':
1207 case 'd':
1208 if (&OptChar == ExpandChar) {
1209 if (OptChar == 'd') {
1210 DAL.AddFlagArg(A, Opts.getOption(options::OPT_O0));
1211 } else {
1212 if (OptChar == '1') {
1213 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "s");
1214 } else if (OptChar == '2' || OptChar == 'x') {
1215 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
1216 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "2");
1217 }
David Majnemer259d71a2016-01-21 23:01:11 +00001218 if (SupportsForcingFramePointer &&
1219 !DAL.hasArgNoClaim(options::OPT_fno_omit_frame_pointer))
Hans Wennborg21d73d22016-01-12 23:17:03 +00001220 DAL.AddFlagArg(A,
1221 Opts.getOption(options::OPT_fomit_frame_pointer));
1222 if (OptChar == '1' || OptChar == '2')
1223 DAL.AddFlagArg(A,
1224 Opts.getOption(options::OPT_ffunction_sections));
1225 }
1226 }
1227 break;
1228 case 'b':
Hans Wennborg3270bdb2016-05-24 21:23:29 +00001229 if (I + 1 != E && isdigit(OptStr[I + 1])) {
1230 switch (OptStr[I + 1]) {
1231 case '0':
1232 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_inline));
1233 break;
1234 case '1':
Hans Wennborg44d061a2016-06-22 16:56:16 +00001235 DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_hint_functions));
Hans Wennborg3270bdb2016-05-24 21:23:29 +00001236 break;
1237 case '2':
1238 DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_functions));
1239 break;
1240 }
Hans Wennborg21d73d22016-01-12 23:17:03 +00001241 ++I;
Hans Wennborg3270bdb2016-05-24 21:23:29 +00001242 }
Hans Wennborg21d73d22016-01-12 23:17:03 +00001243 break;
1244 case 'g':
1245 break;
1246 case 'i':
1247 if (I + 1 != E && OptStr[I + 1] == '-') {
1248 ++I;
1249 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_builtin));
1250 } else {
1251 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
1252 }
1253 break;
1254 case 's':
1255 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "s");
1256 break;
1257 case 't':
1258 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "2");
1259 break;
1260 case 'y': {
1261 bool OmitFramePointer = true;
1262 if (I + 1 != E && OptStr[I + 1] == '-') {
1263 OmitFramePointer = false;
1264 ++I;
1265 }
1266 if (SupportsForcingFramePointer) {
1267 if (OmitFramePointer)
1268 DAL.AddFlagArg(A,
1269 Opts.getOption(options::OPT_fomit_frame_pointer));
1270 else
1271 DAL.AddFlagArg(
1272 A, Opts.getOption(options::OPT_fno_omit_frame_pointer));
Nico Weber9c3fca32016-03-23 15:37:41 +00001273 } else {
1274 // Don't warn about /Oy- in 64-bit builds (where
1275 // SupportsForcingFramePointer is false). The flag having no effect
1276 // there is a compiler-internal optimization, and people shouldn't have
1277 // to special-case their build files for 64-bit clang-cl.
1278 A->claim();
Hans Wennborg21d73d22016-01-12 23:17:03 +00001279 }
1280 break;
1281 }
1282 }
1283 }
1284}
1285
1286static void TranslateDArg(Arg *A, llvm::opt::DerivedArgList &DAL,
1287 const OptTable &Opts) {
1288 assert(A->getOption().matches(options::OPT_D));
1289
1290 StringRef Val = A->getValue();
1291 size_t Hash = Val.find('#');
1292 if (Hash == StringRef::npos || Hash > Val.find('=')) {
1293 DAL.append(A);
1294 return;
1295 }
1296
1297 std::string NewVal = Val;
1298 NewVal[Hash] = '=';
1299 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_D), NewVal);
1300}
1301
David Majnemer015ce0f2015-07-27 07:32:11 +00001302llvm::opt::DerivedArgList *
1303MSVCToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args,
Samuel Antao31fef982016-10-27 17:39:44 +00001304 StringRef BoundArch, Action::OffloadKind) const {
David Majnemer015ce0f2015-07-27 07:32:11 +00001305 DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
1306 const OptTable &Opts = getDriver().getOpts();
1307
David Majnemer7ab76f22015-08-25 00:46:45 +00001308 // /Oy and /Oy- only has an effect under X86-32.
1309 bool SupportsForcingFramePointer = getArch() == llvm::Triple::x86;
1310
David Majnemer015ce0f2015-07-27 07:32:11 +00001311 // The -O[12xd] flag actually expands to several flags. We must desugar the
1312 // flags so that options embedded can be negated. For example, the '-O2' flag
1313 // enables '-Oy'. Expanding '-O2' into its constituent flags allows us to
1314 // correctly handle '-O2 -Oy-' where the trailing '-Oy-' disables a single
1315 // aspect of '-O2'.
1316 //
1317 // Note that this expansion logic only applies to the *last* of '[12xd]'.
1318
1319 // First step is to search for the character we'd like to expand.
1320 const char *ExpandChar = nullptr;
1321 for (Arg *A : Args) {
1322 if (!A->getOption().matches(options::OPT__SLASH_O))
1323 continue;
1324 StringRef OptStr = A->getValue();
1325 for (size_t I = 0, E = OptStr.size(); I != E; ++I) {
Hans Wennborgdebfed92016-05-25 00:43:45 +00001326 char OptChar = OptStr[I];
1327 char PrevChar = I > 0 ? OptStr[I - 1] : '0';
1328 if (PrevChar == 'b') {
1329 // OptChar does not expand; it's an argument to the previous char.
1330 continue;
1331 }
David Majnemer015ce0f2015-07-27 07:32:11 +00001332 if (OptChar == '1' || OptChar == '2' || OptChar == 'x' || OptChar == 'd')
1333 ExpandChar = OptStr.data() + I;
1334 }
1335 }
1336
David Majnemer015ce0f2015-07-27 07:32:11 +00001337 for (Arg *A : Args) {
Hans Wennborg21d73d22016-01-12 23:17:03 +00001338 if (A->getOption().matches(options::OPT__SLASH_O)) {
1339 // The -O flag actually takes an amalgam of other options. For example,
1340 // '/Ogyb2' is equivalent to '/Og' '/Oy' '/Ob2'.
1341 TranslateOptArg(A, *DAL, SupportsForcingFramePointer, ExpandChar, Opts);
1342 } else if (A->getOption().matches(options::OPT_D)) {
1343 // Translate -Dfoo#bar into -Dfoo=bar.
1344 TranslateDArg(A, *DAL, Opts);
1345 } else {
David Majnemer015ce0f2015-07-27 07:32:11 +00001346 DAL->append(A);
David Majnemer015ce0f2015-07-27 07:32:11 +00001347 }
1348 }
Hans Wennborg21d73d22016-01-12 23:17:03 +00001349
David Majnemer015ce0f2015-07-27 07:32:11 +00001350 return DAL;
1351}