xref: /freebsd/contrib/llvm-project/clang/lib/Driver/ToolChains/MSVC.cpp (revision 924226fba12cc9a228c73b956e1b7fa24c60b055)
1 //===-- MSVC.cpp - MSVC ToolChain Implementations -------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "MSVC.h"
10 #include "CommonArgs.h"
11 #include "Darwin.h"
12 #include "clang/Basic/CharInfo.h"
13 #include "clang/Basic/Version.h"
14 #include "clang/Config/config.h"
15 #include "clang/Driver/Compilation.h"
16 #include "clang/Driver/Driver.h"
17 #include "clang/Driver/DriverDiagnostic.h"
18 #include "clang/Driver/Options.h"
19 #include "clang/Driver/SanitizerArgs.h"
20 #include "llvm/ADT/StringExtras.h"
21 #include "llvm/ADT/StringSwitch.h"
22 #include "llvm/Option/Arg.h"
23 #include "llvm/Option/ArgList.h"
24 #include "llvm/Support/ConvertUTF.h"
25 #include "llvm/Support/ErrorHandling.h"
26 #include "llvm/Support/FileSystem.h"
27 #include "llvm/Support/Host.h"
28 #include "llvm/Support/MemoryBuffer.h"
29 #include "llvm/Support/Path.h"
30 #include "llvm/Support/Process.h"
31 #include "llvm/Support/VirtualFileSystem.h"
32 #include <cstdio>
33 
34 #ifdef _WIN32
35   #define WIN32_LEAN_AND_MEAN
36   #define NOGDI
37   #ifndef NOMINMAX
38     #define NOMINMAX
39   #endif
40   #include <windows.h>
41 #endif
42 
43 #ifdef _MSC_VER
44 // Don't support SetupApi on MinGW.
45 #define USE_MSVC_SETUP_API
46 
47 // Make sure this comes before MSVCSetupApi.h
48 #include <comdef.h>
49 
50 #ifdef __clang__
51 #pragma clang diagnostic push
52 #pragma clang diagnostic ignored "-Wnon-virtual-dtor"
53 #endif
54 #include "MSVCSetupApi.h"
55 #ifdef __clang__
56 #pragma clang diagnostic pop
57 #endif
58 #include "llvm/Support/COM.h"
59 _COM_SMARTPTR_TYPEDEF(ISetupConfiguration, __uuidof(ISetupConfiguration));
60 _COM_SMARTPTR_TYPEDEF(ISetupConfiguration2, __uuidof(ISetupConfiguration2));
61 _COM_SMARTPTR_TYPEDEF(ISetupHelper, __uuidof(ISetupHelper));
62 _COM_SMARTPTR_TYPEDEF(IEnumSetupInstances, __uuidof(IEnumSetupInstances));
63 _COM_SMARTPTR_TYPEDEF(ISetupInstance, __uuidof(ISetupInstance));
64 _COM_SMARTPTR_TYPEDEF(ISetupInstance2, __uuidof(ISetupInstance2));
65 #endif
66 
67 using namespace clang::driver;
68 using namespace clang::driver::toolchains;
69 using namespace clang::driver::tools;
70 using namespace clang;
71 using namespace llvm::opt;
72 
73 // Windows SDKs and VC Toolchains group their contents into subdirectories based
74 // on the target architecture. This function converts an llvm::Triple::ArchType
75 // to the corresponding subdirectory name.
76 static const char *llvmArchToWindowsSDKArch(llvm::Triple::ArchType Arch) {
77   using ArchType = llvm::Triple::ArchType;
78   switch (Arch) {
79   case ArchType::x86:
80     return "x86";
81   case ArchType::x86_64:
82     return "x64";
83   case ArchType::arm:
84     return "arm";
85   case ArchType::aarch64:
86     return "arm64";
87   default:
88     return "";
89   }
90 }
91 
92 // Similar to the above function, but for Visual Studios before VS2017.
93 static const char *llvmArchToLegacyVCArch(llvm::Triple::ArchType Arch) {
94   using ArchType = llvm::Triple::ArchType;
95   switch (Arch) {
96   case ArchType::x86:
97     // x86 is default in legacy VC toolchains.
98     // e.g. x86 libs are directly in /lib as opposed to /lib/x86.
99     return "";
100   case ArchType::x86_64:
101     return "amd64";
102   case ArchType::arm:
103     return "arm";
104   case ArchType::aarch64:
105     return "arm64";
106   default:
107     return "";
108   }
109 }
110 
111 // Similar to the above function, but for DevDiv internal builds.
112 static const char *llvmArchToDevDivInternalArch(llvm::Triple::ArchType Arch) {
113   using ArchType = llvm::Triple::ArchType;
114   switch (Arch) {
115   case ArchType::x86:
116     return "i386";
117   case ArchType::x86_64:
118     return "amd64";
119   case ArchType::arm:
120     return "arm";
121   case ArchType::aarch64:
122     return "arm64";
123   default:
124     return "";
125   }
126 }
127 
128 static bool canExecute(llvm::vfs::FileSystem &VFS, StringRef Path) {
129   auto Status = VFS.status(Path);
130   if (!Status)
131     return false;
132   return (Status->getPermissions() & llvm::sys::fs::perms::all_exe) != 0;
133 }
134 
135 // Defined below.
136 // Forward declare this so there aren't too many things above the constructor.
137 static bool getSystemRegistryString(const char *keyPath, const char *valueName,
138                                     std::string &value, std::string *phValue);
139 
140 static std::string getHighestNumericTupleInDirectory(llvm::vfs::FileSystem &VFS,
141                                                      StringRef Directory) {
142   std::string Highest;
143   llvm::VersionTuple HighestTuple;
144 
145   std::error_code EC;
146   for (llvm::vfs::directory_iterator DirIt = VFS.dir_begin(Directory, EC),
147                                      DirEnd;
148        !EC && DirIt != DirEnd; DirIt.increment(EC)) {
149     auto Status = VFS.status(DirIt->path());
150     if (!Status || !Status->isDirectory())
151       continue;
152     StringRef CandidateName = llvm::sys::path::filename(DirIt->path());
153     llvm::VersionTuple Tuple;
154     if (Tuple.tryParse(CandidateName)) // tryParse() returns true on error.
155       continue;
156     if (Tuple > HighestTuple) {
157       HighestTuple = Tuple;
158       Highest = CandidateName.str();
159     }
160   }
161 
162   return Highest;
163 }
164 
165 // Check command line arguments to try and find a toolchain.
166 static bool
167 findVCToolChainViaCommandLine(llvm::vfs::FileSystem &VFS, const ArgList &Args,
168                               std::string &Path,
169                               MSVCToolChain::ToolsetLayout &VSLayout) {
170   // Don't validate the input; trust the value supplied by the user.
171   // The primary motivation is to prevent unnecessary file and registry access.
172   if (Arg *A = Args.getLastArg(options::OPT__SLASH_vctoolsdir,
173                                options::OPT__SLASH_winsysroot)) {
174     if (A->getOption().getID() == options::OPT__SLASH_winsysroot) {
175       llvm::SmallString<128> ToolsPath(A->getValue());
176       llvm::sys::path::append(ToolsPath, "VC", "Tools", "MSVC");
177       std::string VCToolsVersion;
178       if (Arg *A = Args.getLastArg(options::OPT__SLASH_vctoolsversion))
179         VCToolsVersion = A->getValue();
180       else
181         VCToolsVersion = getHighestNumericTupleInDirectory(VFS, ToolsPath);
182       llvm::sys::path::append(ToolsPath, VCToolsVersion);
183       Path = std::string(ToolsPath.str());
184     } else {
185       Path = A->getValue();
186     }
187     VSLayout = MSVCToolChain::ToolsetLayout::VS2017OrNewer;
188     return true;
189   }
190   return false;
191 }
192 
193 // Check various environment variables to try and find a toolchain.
194 static bool
195 findVCToolChainViaEnvironment(llvm::vfs::FileSystem &VFS, std::string &Path,
196                               MSVCToolChain::ToolsetLayout &VSLayout) {
197   // These variables are typically set by vcvarsall.bat
198   // when launching a developer command prompt.
199   if (llvm::Optional<std::string> VCToolsInstallDir =
200           llvm::sys::Process::GetEnv("VCToolsInstallDir")) {
201     // This is only set by newer Visual Studios, and it leads straight to
202     // the toolchain directory.
203     Path = std::move(*VCToolsInstallDir);
204     VSLayout = MSVCToolChain::ToolsetLayout::VS2017OrNewer;
205     return true;
206   }
207   if (llvm::Optional<std::string> VCInstallDir =
208           llvm::sys::Process::GetEnv("VCINSTALLDIR")) {
209     // If the previous variable isn't set but this one is, then we've found
210     // an older Visual Studio. This variable is set by newer Visual Studios too,
211     // so this check has to appear second.
212     // In older Visual Studios, the VC directory is the toolchain.
213     Path = std::move(*VCInstallDir);
214     VSLayout = MSVCToolChain::ToolsetLayout::OlderVS;
215     return true;
216   }
217 
218   // We couldn't find any VC environment variables. Let's walk through PATH and
219   // see if it leads us to a VC toolchain bin directory. If it does, pick the
220   // first one that we find.
221   if (llvm::Optional<std::string> PathEnv =
222           llvm::sys::Process::GetEnv("PATH")) {
223     llvm::SmallVector<llvm::StringRef, 8> PathEntries;
224     llvm::StringRef(*PathEnv).split(PathEntries, llvm::sys::EnvPathSeparator);
225     for (llvm::StringRef PathEntry : PathEntries) {
226       if (PathEntry.empty())
227         continue;
228 
229       llvm::SmallString<256> ExeTestPath;
230 
231       // If cl.exe doesn't exist, then this definitely isn't a VC toolchain.
232       ExeTestPath = PathEntry;
233       llvm::sys::path::append(ExeTestPath, "cl.exe");
234       if (!VFS.exists(ExeTestPath))
235         continue;
236 
237       // cl.exe existing isn't a conclusive test for a VC toolchain; clang also
238       // has a cl.exe. So let's check for link.exe too.
239       ExeTestPath = PathEntry;
240       llvm::sys::path::append(ExeTestPath, "link.exe");
241       if (!VFS.exists(ExeTestPath))
242         continue;
243 
244       // whatever/VC/bin --> old toolchain, VC dir is toolchain dir.
245       llvm::StringRef TestPath = PathEntry;
246       bool IsBin =
247           llvm::sys::path::filename(TestPath).equals_insensitive("bin");
248       if (!IsBin) {
249         // Strip any architecture subdir like "amd64".
250         TestPath = llvm::sys::path::parent_path(TestPath);
251         IsBin = llvm::sys::path::filename(TestPath).equals_insensitive("bin");
252       }
253       if (IsBin) {
254         llvm::StringRef ParentPath = llvm::sys::path::parent_path(TestPath);
255         llvm::StringRef ParentFilename = llvm::sys::path::filename(ParentPath);
256         if (ParentFilename.equals_insensitive("VC")) {
257           Path = std::string(ParentPath);
258           VSLayout = MSVCToolChain::ToolsetLayout::OlderVS;
259           return true;
260         }
261         if (ParentFilename.equals_insensitive("x86ret") ||
262             ParentFilename.equals_insensitive("x86chk") ||
263             ParentFilename.equals_insensitive("amd64ret") ||
264             ParentFilename.equals_insensitive("amd64chk")) {
265           Path = std::string(ParentPath);
266           VSLayout = MSVCToolChain::ToolsetLayout::DevDivInternal;
267           return true;
268         }
269 
270       } else {
271         // This could be a new (>=VS2017) toolchain. If it is, we should find
272         // path components with these prefixes when walking backwards through
273         // the path.
274         // Note: empty strings match anything.
275         llvm::StringRef ExpectedPrefixes[] = {"",     "Host",  "bin", "",
276                                               "MSVC", "Tools", "VC"};
277 
278         auto It = llvm::sys::path::rbegin(PathEntry);
279         auto End = llvm::sys::path::rend(PathEntry);
280         for (llvm::StringRef Prefix : ExpectedPrefixes) {
281           if (It == End)
282             goto NotAToolChain;
283           if (!It->startswith_insensitive(Prefix))
284             goto NotAToolChain;
285           ++It;
286         }
287 
288         // We've found a new toolchain!
289         // Back up 3 times (/bin/Host/arch) to get the root path.
290         llvm::StringRef ToolChainPath(PathEntry);
291         for (int i = 0; i < 3; ++i)
292           ToolChainPath = llvm::sys::path::parent_path(ToolChainPath);
293 
294         Path = std::string(ToolChainPath);
295         VSLayout = MSVCToolChain::ToolsetLayout::VS2017OrNewer;
296         return true;
297       }
298 
299     NotAToolChain:
300       continue;
301     }
302   }
303   return false;
304 }
305 
306 // Query the Setup Config server for installs, then pick the newest version
307 // and find its default VC toolchain.
308 // This is the preferred way to discover new Visual Studios, as they're no
309 // longer listed in the registry.
310 static bool
311 findVCToolChainViaSetupConfig(llvm::vfs::FileSystem &VFS, std::string &Path,
312                               MSVCToolChain::ToolsetLayout &VSLayout) {
313 #if !defined(USE_MSVC_SETUP_API)
314   return false;
315 #else
316   // FIXME: This really should be done once in the top-level program's main
317   // function, as it may have already been initialized with a different
318   // threading model otherwise.
319   llvm::sys::InitializeCOMRAII COM(llvm::sys::COMThreadingMode::SingleThreaded);
320   HRESULT HR;
321 
322   // _com_ptr_t will throw a _com_error if a COM calls fail.
323   // The LLVM coding standards forbid exception handling, so we'll have to
324   // stop them from being thrown in the first place.
325   // The destructor will put the regular error handler back when we leave
326   // this scope.
327   struct SuppressCOMErrorsRAII {
328     static void __stdcall handler(HRESULT hr, IErrorInfo *perrinfo) {}
329 
330     SuppressCOMErrorsRAII() { _set_com_error_handler(handler); }
331 
332     ~SuppressCOMErrorsRAII() { _set_com_error_handler(_com_raise_error); }
333 
334   } COMErrorSuppressor;
335 
336   ISetupConfigurationPtr Query;
337   HR = Query.CreateInstance(__uuidof(SetupConfiguration));
338   if (FAILED(HR))
339     return false;
340 
341   IEnumSetupInstancesPtr EnumInstances;
342   HR = ISetupConfiguration2Ptr(Query)->EnumAllInstances(&EnumInstances);
343   if (FAILED(HR))
344     return false;
345 
346   ISetupInstancePtr Instance;
347   HR = EnumInstances->Next(1, &Instance, nullptr);
348   if (HR != S_OK)
349     return false;
350 
351   ISetupInstancePtr NewestInstance;
352   Optional<uint64_t> NewestVersionNum;
353   do {
354     bstr_t VersionString;
355     uint64_t VersionNum;
356     HR = Instance->GetInstallationVersion(VersionString.GetAddress());
357     if (FAILED(HR))
358       continue;
359     HR = ISetupHelperPtr(Query)->ParseVersion(VersionString, &VersionNum);
360     if (FAILED(HR))
361       continue;
362     if (!NewestVersionNum || (VersionNum > NewestVersionNum)) {
363       NewestInstance = Instance;
364       NewestVersionNum = VersionNum;
365     }
366   } while ((HR = EnumInstances->Next(1, &Instance, nullptr)) == S_OK);
367 
368   if (!NewestInstance)
369     return false;
370 
371   bstr_t VCPathWide;
372   HR = NewestInstance->ResolvePath(L"VC", VCPathWide.GetAddress());
373   if (FAILED(HR))
374     return false;
375 
376   std::string VCRootPath;
377   llvm::convertWideToUTF8(std::wstring(VCPathWide), VCRootPath);
378 
379   llvm::SmallString<256> ToolsVersionFilePath(VCRootPath);
380   llvm::sys::path::append(ToolsVersionFilePath, "Auxiliary", "Build",
381                           "Microsoft.VCToolsVersion.default.txt");
382 
383   auto ToolsVersionFile = llvm::MemoryBuffer::getFile(ToolsVersionFilePath);
384   if (!ToolsVersionFile)
385     return false;
386 
387   llvm::SmallString<256> ToolchainPath(VCRootPath);
388   llvm::sys::path::append(ToolchainPath, "Tools", "MSVC",
389                           ToolsVersionFile->get()->getBuffer().rtrim());
390   auto Status = VFS.status(ToolchainPath);
391   if (!Status || !Status->isDirectory())
392     return false;
393 
394   Path = std::string(ToolchainPath.str());
395   VSLayout = MSVCToolChain::ToolsetLayout::VS2017OrNewer;
396   return true;
397 #endif
398 }
399 
400 // Look in the registry for Visual Studio installs, and use that to get
401 // a toolchain path. VS2017 and newer don't get added to the registry.
402 // So if we find something here, we know that it's an older version.
403 static bool findVCToolChainViaRegistry(std::string &Path,
404                                        MSVCToolChain::ToolsetLayout &VSLayout) {
405   std::string VSInstallPath;
406   if (getSystemRegistryString(R"(SOFTWARE\Microsoft\VisualStudio\$VERSION)",
407                               "InstallDir", VSInstallPath, nullptr) ||
408       getSystemRegistryString(R"(SOFTWARE\Microsoft\VCExpress\$VERSION)",
409                               "InstallDir", VSInstallPath, nullptr)) {
410     if (!VSInstallPath.empty()) {
411       llvm::SmallString<256> VCPath(llvm::StringRef(
412           VSInstallPath.c_str(), VSInstallPath.find(R"(\Common7\IDE)")));
413       llvm::sys::path::append(VCPath, "VC");
414 
415       Path = std::string(VCPath.str());
416       VSLayout = MSVCToolChain::ToolsetLayout::OlderVS;
417       return true;
418     }
419   }
420   return false;
421 }
422 
423 // Try to find Exe from a Visual Studio distribution.  This first tries to find
424 // an installed copy of Visual Studio and, failing that, looks in the PATH,
425 // making sure that whatever executable that's found is not a same-named exe
426 // from clang itself to prevent clang from falling back to itself.
427 static std::string FindVisualStudioExecutable(const ToolChain &TC,
428                                               const char *Exe) {
429   const auto &MSVC = static_cast<const toolchains::MSVCToolChain &>(TC);
430   SmallString<128> FilePath(MSVC.getSubDirectoryPath(
431       toolchains::MSVCToolChain::SubDirectoryType::Bin));
432   llvm::sys::path::append(FilePath, Exe);
433   return std::string(canExecute(TC.getVFS(), FilePath) ? FilePath.str() : Exe);
434 }
435 
436 void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA,
437                                         const InputInfo &Output,
438                                         const InputInfoList &Inputs,
439                                         const ArgList &Args,
440                                         const char *LinkingOutput) const {
441   ArgStringList CmdArgs;
442 
443   auto &TC = static_cast<const toolchains::MSVCToolChain &>(getToolChain());
444 
445   assert((Output.isFilename() || Output.isNothing()) && "invalid output");
446   if (Output.isFilename())
447     CmdArgs.push_back(
448         Args.MakeArgString(std::string("-out:") + Output.getFilename()));
449 
450   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles) &&
451       !C.getDriver().IsCLMode()) {
452     CmdArgs.push_back("-defaultlib:libcmt");
453     CmdArgs.push_back("-defaultlib:oldnames");
454   }
455 
456   // If the VC environment hasn't been configured (perhaps because the user
457   // did not run vcvarsall), try to build a consistent link environment.  If
458   // the environment variable is set however, assume the user knows what
459   // they're doing. If the user passes /vctoolsdir or /winsdkdir, trust that
460   // over env vars.
461   if (const Arg *A = Args.getLastArg(options::OPT__SLASH_diasdkdir,
462                                      options::OPT__SLASH_winsysroot)) {
463     // cl.exe doesn't find the DIA SDK automatically, so this too requires
464     // explicit flags and doesn't automatically look in "DIA SDK" relative
465     // to the path we found for VCToolChainPath.
466     llvm::SmallString<128> DIAPath(A->getValue());
467     if (A->getOption().getID() == options::OPT__SLASH_winsysroot)
468       llvm::sys::path::append(DIAPath, "DIA SDK");
469 
470     // The DIA SDK always uses the legacy vc arch, even in new MSVC versions.
471     llvm::sys::path::append(DIAPath, "lib",
472                             llvmArchToLegacyVCArch(TC.getArch()));
473     CmdArgs.push_back(Args.MakeArgString(Twine("-libpath:") + DIAPath));
474   }
475   if (!llvm::sys::Process::GetEnv("LIB") ||
476       Args.getLastArg(options::OPT__SLASH_vctoolsdir,
477                       options::OPT__SLASH_winsysroot)) {
478     CmdArgs.push_back(Args.MakeArgString(
479         Twine("-libpath:") +
480         TC.getSubDirectoryPath(
481             toolchains::MSVCToolChain::SubDirectoryType::Lib)));
482     CmdArgs.push_back(Args.MakeArgString(
483         Twine("-libpath:") +
484         TC.getSubDirectoryPath(toolchains::MSVCToolChain::SubDirectoryType::Lib,
485                                "atlmfc")));
486   }
487   if (!llvm::sys::Process::GetEnv("LIB") ||
488       Args.getLastArg(options::OPT__SLASH_winsdkdir,
489                       options::OPT__SLASH_winsysroot)) {
490     if (TC.useUniversalCRT()) {
491       std::string UniversalCRTLibPath;
492       if (TC.getUniversalCRTLibraryPath(Args, UniversalCRTLibPath))
493         CmdArgs.push_back(
494             Args.MakeArgString(Twine("-libpath:") + UniversalCRTLibPath));
495     }
496     std::string WindowsSdkLibPath;
497     if (TC.getWindowsSDKLibraryPath(Args, WindowsSdkLibPath))
498       CmdArgs.push_back(
499           Args.MakeArgString(std::string("-libpath:") + WindowsSdkLibPath));
500   }
501 
502   // Add the compiler-rt library directories to libpath if they exist to help
503   // the linker find the various sanitizer, builtin, and profiling runtimes.
504   for (const auto &LibPath : TC.getLibraryPaths()) {
505     if (TC.getVFS().exists(LibPath))
506       CmdArgs.push_back(Args.MakeArgString("-libpath:" + LibPath));
507   }
508   auto CRTPath = TC.getCompilerRTPath();
509   if (TC.getVFS().exists(CRTPath))
510     CmdArgs.push_back(Args.MakeArgString("-libpath:" + CRTPath));
511 
512   if (!C.getDriver().IsCLMode() && Args.hasArg(options::OPT_L))
513     for (const auto &LibPath : Args.getAllArgValues(options::OPT_L))
514       CmdArgs.push_back(Args.MakeArgString("-libpath:" + LibPath));
515 
516   CmdArgs.push_back("-nologo");
517 
518   if (Args.hasArg(options::OPT_g_Group, options::OPT__SLASH_Z7))
519     CmdArgs.push_back("-debug");
520 
521   // If we specify /hotpatch, let the linker add padding in front of each
522   // function, like MSVC does.
523   if (Args.hasArg(options::OPT_fms_hotpatch, options::OPT__SLASH_hotpatch))
524     CmdArgs.push_back("-functionpadmin");
525 
526   // Pass on /Brepro if it was passed to the compiler.
527   // Note that /Brepro maps to -mno-incremental-linker-compatible.
528   bool DefaultIncrementalLinkerCompatible =
529       C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment();
530   if (!Args.hasFlag(options::OPT_mincremental_linker_compatible,
531                     options::OPT_mno_incremental_linker_compatible,
532                     DefaultIncrementalLinkerCompatible))
533     CmdArgs.push_back("-Brepro");
534 
535   bool DLL = Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd,
536                          options::OPT_shared);
537   if (DLL) {
538     CmdArgs.push_back(Args.MakeArgString("-dll"));
539 
540     SmallString<128> ImplibName(Output.getFilename());
541     llvm::sys::path::replace_extension(ImplibName, "lib");
542     CmdArgs.push_back(Args.MakeArgString(std::string("-implib:") + ImplibName));
543   }
544 
545   if (TC.getSanitizerArgs(Args).needsFuzzer()) {
546     if (!Args.hasArg(options::OPT_shared))
547       CmdArgs.push_back(
548           Args.MakeArgString(std::string("-wholearchive:") +
549                              TC.getCompilerRTArgString(Args, "fuzzer")));
550     CmdArgs.push_back(Args.MakeArgString("-debug"));
551     // Prevent the linker from padding sections we use for instrumentation
552     // arrays.
553     CmdArgs.push_back(Args.MakeArgString("-incremental:no"));
554   }
555 
556   if (TC.getSanitizerArgs(Args).needsAsanRt()) {
557     CmdArgs.push_back(Args.MakeArgString("-debug"));
558     CmdArgs.push_back(Args.MakeArgString("-incremental:no"));
559     if (TC.getSanitizerArgs(Args).needsSharedRt() ||
560         Args.hasArg(options::OPT__SLASH_MD, options::OPT__SLASH_MDd)) {
561       for (const auto &Lib : {"asan_dynamic", "asan_dynamic_runtime_thunk"})
562         CmdArgs.push_back(TC.getCompilerRTArgString(Args, Lib));
563       // Make sure the dynamic runtime thunk is not optimized out at link time
564       // to ensure proper SEH handling.
565       CmdArgs.push_back(Args.MakeArgString(
566           TC.getArch() == llvm::Triple::x86
567               ? "-include:___asan_seh_interceptor"
568               : "-include:__asan_seh_interceptor"));
569       // Make sure the linker consider all object files from the dynamic runtime
570       // thunk.
571       CmdArgs.push_back(Args.MakeArgString(std::string("-wholearchive:") +
572           TC.getCompilerRT(Args, "asan_dynamic_runtime_thunk")));
573     } else if (DLL) {
574       CmdArgs.push_back(TC.getCompilerRTArgString(Args, "asan_dll_thunk"));
575     } else {
576       for (const auto &Lib : {"asan", "asan_cxx"}) {
577         CmdArgs.push_back(TC.getCompilerRTArgString(Args, Lib));
578         // Make sure the linker consider all object files from the static lib.
579         // This is necessary because instrumented dlls need access to all the
580         // interface exported by the static lib in the main executable.
581         CmdArgs.push_back(Args.MakeArgString(std::string("-wholearchive:") +
582             TC.getCompilerRT(Args, Lib)));
583       }
584     }
585   }
586 
587   Args.AddAllArgValues(CmdArgs, options::OPT__SLASH_link);
588 
589   // Control Flow Guard checks
590   if (Arg *A = Args.getLastArg(options::OPT__SLASH_guard)) {
591     StringRef GuardArgs = A->getValue();
592     if (GuardArgs.equals_insensitive("cf") ||
593         GuardArgs.equals_insensitive("cf,nochecks")) {
594       // MSVC doesn't yet support the "nochecks" modifier.
595       CmdArgs.push_back("-guard:cf");
596     } else if (GuardArgs.equals_insensitive("cf-")) {
597       CmdArgs.push_back("-guard:cf-");
598     } else if (GuardArgs.equals_insensitive("ehcont")) {
599       CmdArgs.push_back("-guard:ehcont");
600     } else if (GuardArgs.equals_insensitive("ehcont-")) {
601       CmdArgs.push_back("-guard:ehcont-");
602     }
603   }
604 
605   if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
606                    options::OPT_fno_openmp, false)) {
607     CmdArgs.push_back("-nodefaultlib:vcomp.lib");
608     CmdArgs.push_back("-nodefaultlib:vcompd.lib");
609     CmdArgs.push_back(Args.MakeArgString(std::string("-libpath:") +
610                                          TC.getDriver().Dir + "/../lib"));
611     switch (TC.getDriver().getOpenMPRuntime(Args)) {
612     case Driver::OMPRT_OMP:
613       CmdArgs.push_back("-defaultlib:libomp.lib");
614       break;
615     case Driver::OMPRT_IOMP5:
616       CmdArgs.push_back("-defaultlib:libiomp5md.lib");
617       break;
618     case Driver::OMPRT_GOMP:
619       break;
620     case Driver::OMPRT_Unknown:
621       // Already diagnosed.
622       break;
623     }
624   }
625 
626   // Add compiler-rt lib in case if it was explicitly
627   // specified as an argument for --rtlib option.
628   if (!Args.hasArg(options::OPT_nostdlib)) {
629     AddRunTimeLibs(TC, TC.getDriver(), CmdArgs, Args);
630   }
631 
632   // Add filenames, libraries, and other linker inputs.
633   for (const auto &Input : Inputs) {
634     if (Input.isFilename()) {
635       CmdArgs.push_back(Input.getFilename());
636       continue;
637     }
638 
639     const Arg &A = Input.getInputArg();
640 
641     // Render -l options differently for the MSVC linker.
642     if (A.getOption().matches(options::OPT_l)) {
643       StringRef Lib = A.getValue();
644       const char *LinkLibArg;
645       if (Lib.endswith(".lib"))
646         LinkLibArg = Args.MakeArgString(Lib);
647       else
648         LinkLibArg = Args.MakeArgString(Lib + ".lib");
649       CmdArgs.push_back(LinkLibArg);
650       continue;
651     }
652 
653     // Otherwise, this is some other kind of linker input option like -Wl, -z,
654     // or -L. Render it, even if MSVC doesn't understand it.
655     A.renderAsInput(Args, CmdArgs);
656   }
657 
658   TC.addProfileRTLibs(Args, CmdArgs);
659 
660   std::vector<const char *> Environment;
661 
662   // We need to special case some linker paths.  In the case of lld, we need to
663   // translate 'lld' into 'lld-link', and in the case of the regular msvc
664   // linker, we need to use a special search algorithm.
665   llvm::SmallString<128> linkPath;
666   StringRef Linker
667     = Args.getLastArgValue(options::OPT_fuse_ld_EQ, CLANG_DEFAULT_LINKER);
668   if (Linker.empty())
669     Linker = "link";
670   if (Linker.equals_insensitive("lld"))
671     Linker = "lld-link";
672 
673   if (Linker.equals_insensitive("link")) {
674     // If we're using the MSVC linker, it's not sufficient to just use link
675     // from the program PATH, because other environments like GnuWin32 install
676     // their own link.exe which may come first.
677     linkPath = FindVisualStudioExecutable(TC, "link.exe");
678 
679     if (!TC.FoundMSVCInstall() && !canExecute(TC.getVFS(), linkPath)) {
680       llvm::SmallString<128> ClPath;
681       ClPath = TC.GetProgramPath("cl.exe");
682       if (canExecute(TC.getVFS(), ClPath)) {
683         linkPath = llvm::sys::path::parent_path(ClPath);
684         llvm::sys::path::append(linkPath, "link.exe");
685         if (!canExecute(TC.getVFS(), linkPath))
686           C.getDriver().Diag(clang::diag::warn_drv_msvc_not_found);
687       } else {
688         C.getDriver().Diag(clang::diag::warn_drv_msvc_not_found);
689       }
690     }
691 
692 #ifdef _WIN32
693     // When cross-compiling with VS2017 or newer, link.exe expects to have
694     // its containing bin directory at the top of PATH, followed by the
695     // native target bin directory.
696     // e.g. when compiling for x86 on an x64 host, PATH should start with:
697     // /bin/Hostx64/x86;/bin/Hostx64/x64
698     // This doesn't attempt to handle ToolsetLayout::DevDivInternal.
699     if (TC.getIsVS2017OrNewer() &&
700         llvm::Triple(llvm::sys::getProcessTriple()).getArch() != TC.getArch()) {
701       auto HostArch = llvm::Triple(llvm::sys::getProcessTriple()).getArch();
702 
703       auto EnvBlockWide =
704           std::unique_ptr<wchar_t[], decltype(&FreeEnvironmentStringsW)>(
705               GetEnvironmentStringsW(), FreeEnvironmentStringsW);
706       if (!EnvBlockWide)
707         goto SkipSettingEnvironment;
708 
709       size_t EnvCount = 0;
710       size_t EnvBlockLen = 0;
711       while (EnvBlockWide[EnvBlockLen] != L'\0') {
712         ++EnvCount;
713         EnvBlockLen += std::wcslen(&EnvBlockWide[EnvBlockLen]) +
714                        1 /*string null-terminator*/;
715       }
716       ++EnvBlockLen; // add the block null-terminator
717 
718       std::string EnvBlock;
719       if (!llvm::convertUTF16ToUTF8String(
720               llvm::ArrayRef<char>(reinterpret_cast<char *>(EnvBlockWide.get()),
721                                    EnvBlockLen * sizeof(EnvBlockWide[0])),
722               EnvBlock))
723         goto SkipSettingEnvironment;
724 
725       Environment.reserve(EnvCount);
726 
727       // Now loop over each string in the block and copy them into the
728       // environment vector, adjusting the PATH variable as needed when we
729       // find it.
730       for (const char *Cursor = EnvBlock.data(); *Cursor != '\0';) {
731         llvm::StringRef EnvVar(Cursor);
732         if (EnvVar.startswith_insensitive("path=")) {
733           using SubDirectoryType = toolchains::MSVCToolChain::SubDirectoryType;
734           constexpr size_t PrefixLen = 5; // strlen("path=")
735           Environment.push_back(Args.MakeArgString(
736               EnvVar.substr(0, PrefixLen) +
737               TC.getSubDirectoryPath(SubDirectoryType::Bin) +
738               llvm::Twine(llvm::sys::EnvPathSeparator) +
739               TC.getSubDirectoryPath(SubDirectoryType::Bin, "", HostArch) +
740               (EnvVar.size() > PrefixLen
741                    ? llvm::Twine(llvm::sys::EnvPathSeparator) +
742                          EnvVar.substr(PrefixLen)
743                    : "")));
744         } else {
745           Environment.push_back(Args.MakeArgString(EnvVar));
746         }
747         Cursor += EnvVar.size() + 1 /*null-terminator*/;
748       }
749     }
750   SkipSettingEnvironment:;
751 #endif
752   } else {
753     linkPath = TC.GetProgramPath(Linker.str().c_str());
754   }
755 
756   auto LinkCmd = std::make_unique<Command>(
757       JA, *this, ResponseFileSupport::AtFileUTF16(),
758       Args.MakeArgString(linkPath), CmdArgs, Inputs, Output);
759   if (!Environment.empty())
760     LinkCmd->setEnvironment(Environment);
761   C.addCommand(std::move(LinkCmd));
762 }
763 
764 MSVCToolChain::MSVCToolChain(const Driver &D, const llvm::Triple &Triple,
765                              const ArgList &Args)
766     : ToolChain(D, Triple, Args), CudaInstallation(D, Triple, Args),
767       RocmInstallation(D, Triple, Args) {
768   getProgramPaths().push_back(getDriver().getInstalledDir());
769   if (getDriver().getInstalledDir() != getDriver().Dir)
770     getProgramPaths().push_back(getDriver().Dir);
771 
772   // Check the command line first, that's the user explicitly telling us what to
773   // use. Check the environment next, in case we're being invoked from a VS
774   // command prompt. Failing that, just try to find the newest Visual Studio
775   // version we can and use its default VC toolchain.
776   findVCToolChainViaCommandLine(getVFS(), Args, VCToolChainPath, VSLayout) ||
777       findVCToolChainViaEnvironment(getVFS(), VCToolChainPath, VSLayout) ||
778       findVCToolChainViaSetupConfig(getVFS(), VCToolChainPath, VSLayout) ||
779       findVCToolChainViaRegistry(VCToolChainPath, VSLayout);
780 }
781 
782 Tool *MSVCToolChain::buildLinker() const {
783   return new tools::visualstudio::Linker(*this);
784 }
785 
786 Tool *MSVCToolChain::buildAssembler() const {
787   if (getTriple().isOSBinFormatMachO())
788     return new tools::darwin::Assembler(*this);
789   getDriver().Diag(clang::diag::err_no_external_assembler);
790   return nullptr;
791 }
792 
793 bool MSVCToolChain::IsIntegratedAssemblerDefault() const {
794   return true;
795 }
796 
797 bool MSVCToolChain::IsUnwindTablesDefault(const ArgList &Args) const {
798   // Don't emit unwind tables by default for MachO targets.
799   if (getTriple().isOSBinFormatMachO())
800     return false;
801 
802   // All non-x86_32 Windows targets require unwind tables. However, LLVM
803   // doesn't know how to generate them for all targets, so only enable
804   // the ones that are actually implemented.
805   return getArch() == llvm::Triple::x86_64 ||
806          getArch() == llvm::Triple::aarch64;
807 }
808 
809 bool MSVCToolChain::isPICDefault() const {
810   return getArch() == llvm::Triple::x86_64 ||
811          getArch() == llvm::Triple::aarch64;
812 }
813 
814 bool MSVCToolChain::isPIEDefault(const llvm::opt::ArgList &Args) const {
815   return false;
816 }
817 
818 bool MSVCToolChain::isPICDefaultForced() const {
819   return getArch() == llvm::Triple::x86_64 ||
820          getArch() == llvm::Triple::aarch64;
821 }
822 
823 void MSVCToolChain::AddCudaIncludeArgs(const ArgList &DriverArgs,
824                                        ArgStringList &CC1Args) const {
825   CudaInstallation.AddCudaIncludeArgs(DriverArgs, CC1Args);
826 }
827 
828 void MSVCToolChain::AddHIPIncludeArgs(const ArgList &DriverArgs,
829                                       ArgStringList &CC1Args) const {
830   RocmInstallation.AddHIPIncludeArgs(DriverArgs, CC1Args);
831 }
832 
833 void MSVCToolChain::printVerboseInfo(raw_ostream &OS) const {
834   CudaInstallation.print(OS);
835   RocmInstallation.print(OS);
836 }
837 
838 // Get the path to a specific subdirectory in the current toolchain for
839 // a given target architecture.
840 // VS2017 changed the VC toolchain layout, so this should be used instead
841 // of hardcoding paths.
842 std::string
843 MSVCToolChain::getSubDirectoryPath(SubDirectoryType Type,
844                                    llvm::StringRef SubdirParent,
845                                    llvm::Triple::ArchType TargetArch) const {
846   const char *SubdirName;
847   const char *IncludeName;
848   switch (VSLayout) {
849   case ToolsetLayout::OlderVS:
850     SubdirName = llvmArchToLegacyVCArch(TargetArch);
851     IncludeName = "include";
852     break;
853   case ToolsetLayout::VS2017OrNewer:
854     SubdirName = llvmArchToWindowsSDKArch(TargetArch);
855     IncludeName = "include";
856     break;
857   case ToolsetLayout::DevDivInternal:
858     SubdirName = llvmArchToDevDivInternalArch(TargetArch);
859     IncludeName = "inc";
860     break;
861   }
862 
863   llvm::SmallString<256> Path(VCToolChainPath);
864   if (!SubdirParent.empty())
865     llvm::sys::path::append(Path, SubdirParent);
866 
867   switch (Type) {
868   case SubDirectoryType::Bin:
869     if (VSLayout == ToolsetLayout::VS2017OrNewer) {
870       const bool HostIsX64 =
871           llvm::Triple(llvm::sys::getProcessTriple()).isArch64Bit();
872       const char *const HostName = HostIsX64 ? "Hostx64" : "Hostx86";
873       llvm::sys::path::append(Path, "bin", HostName, SubdirName);
874     } else { // OlderVS or DevDivInternal
875       llvm::sys::path::append(Path, "bin", SubdirName);
876     }
877     break;
878   case SubDirectoryType::Include:
879     llvm::sys::path::append(Path, IncludeName);
880     break;
881   case SubDirectoryType::Lib:
882     llvm::sys::path::append(Path, "lib", SubdirName);
883     break;
884   }
885   return std::string(Path.str());
886 }
887 
888 #ifdef _WIN32
889 static bool readFullStringValue(HKEY hkey, const char *valueName,
890                                 std::string &value) {
891   std::wstring WideValueName;
892   if (!llvm::ConvertUTF8toWide(valueName, WideValueName))
893     return false;
894 
895   DWORD result = 0;
896   DWORD valueSize = 0;
897   DWORD type = 0;
898   // First just query for the required size.
899   result = RegQueryValueExW(hkey, WideValueName.c_str(), NULL, &type, NULL,
900                             &valueSize);
901   if (result != ERROR_SUCCESS || type != REG_SZ || !valueSize)
902     return false;
903   std::vector<BYTE> buffer(valueSize);
904   result = RegQueryValueExW(hkey, WideValueName.c_str(), NULL, NULL, &buffer[0],
905                             &valueSize);
906   if (result == ERROR_SUCCESS) {
907     std::wstring WideValue(reinterpret_cast<const wchar_t *>(buffer.data()),
908                            valueSize / sizeof(wchar_t));
909     if (valueSize && WideValue.back() == L'\0') {
910       WideValue.pop_back();
911     }
912     // The destination buffer must be empty as an invariant of the conversion
913     // function; but this function is sometimes called in a loop that passes in
914     // the same buffer, however. Simply clear it out so we can overwrite it.
915     value.clear();
916     return llvm::convertWideToUTF8(WideValue, value);
917   }
918   return false;
919 }
920 #endif
921 
922 /// Read registry string.
923 /// This also supports a means to look for high-versioned keys by use
924 /// of a $VERSION placeholder in the key path.
925 /// $VERSION in the key path is a placeholder for the version number,
926 /// causing the highest value path to be searched for and used.
927 /// I.e. "SOFTWARE\\Microsoft\\VisualStudio\\$VERSION".
928 /// There can be additional characters in the component.  Only the numeric
929 /// characters are compared.  This function only searches HKLM.
930 static bool getSystemRegistryString(const char *keyPath, const char *valueName,
931                                     std::string &value, std::string *phValue) {
932 #ifndef _WIN32
933   return false;
934 #else
935   HKEY hRootKey = HKEY_LOCAL_MACHINE;
936   HKEY hKey = NULL;
937   long lResult;
938   bool returnValue = false;
939 
940   const char *placeHolder = strstr(keyPath, "$VERSION");
941   std::string bestName;
942   // If we have a $VERSION placeholder, do the highest-version search.
943   if (placeHolder) {
944     const char *keyEnd = placeHolder - 1;
945     const char *nextKey = placeHolder;
946     // Find end of previous key.
947     while ((keyEnd > keyPath) && (*keyEnd != '\\'))
948       keyEnd--;
949     // Find end of key containing $VERSION.
950     while (*nextKey && (*nextKey != '\\'))
951       nextKey++;
952     size_t partialKeyLength = keyEnd - keyPath;
953     char partialKey[256];
954     if (partialKeyLength >= sizeof(partialKey))
955       partialKeyLength = sizeof(partialKey) - 1;
956     strncpy(partialKey, keyPath, partialKeyLength);
957     partialKey[partialKeyLength] = '\0';
958     HKEY hTopKey = NULL;
959     lResult = RegOpenKeyExA(hRootKey, partialKey, 0, KEY_READ | KEY_WOW64_32KEY,
960                             &hTopKey);
961     if (lResult == ERROR_SUCCESS) {
962       char keyName[256];
963       double bestValue = 0.0;
964       DWORD index, size = sizeof(keyName) - 1;
965       for (index = 0; RegEnumKeyExA(hTopKey, index, keyName, &size, NULL, NULL,
966                                     NULL, NULL) == ERROR_SUCCESS;
967            index++) {
968         const char *sp = keyName;
969         while (*sp && !isDigit(*sp))
970           sp++;
971         if (!*sp)
972           continue;
973         const char *ep = sp + 1;
974         while (*ep && (isDigit(*ep) || (*ep == '.')))
975           ep++;
976         char numBuf[32];
977         strncpy(numBuf, sp, sizeof(numBuf) - 1);
978         numBuf[sizeof(numBuf) - 1] = '\0';
979         double dvalue = strtod(numBuf, NULL);
980         if (dvalue > bestValue) {
981           // Test that InstallDir is indeed there before keeping this index.
982           // Open the chosen key path remainder.
983           bestName = keyName;
984           // Append rest of key.
985           bestName.append(nextKey);
986           lResult = RegOpenKeyExA(hTopKey, bestName.c_str(), 0,
987                                   KEY_READ | KEY_WOW64_32KEY, &hKey);
988           if (lResult == ERROR_SUCCESS) {
989             if (readFullStringValue(hKey, valueName, value)) {
990               bestValue = dvalue;
991               if (phValue)
992                 *phValue = bestName;
993               returnValue = true;
994             }
995             RegCloseKey(hKey);
996           }
997         }
998         size = sizeof(keyName) - 1;
999       }
1000       RegCloseKey(hTopKey);
1001     }
1002   } else {
1003     lResult =
1004         RegOpenKeyExA(hRootKey, keyPath, 0, KEY_READ | KEY_WOW64_32KEY, &hKey);
1005     if (lResult == ERROR_SUCCESS) {
1006       if (readFullStringValue(hKey, valueName, value))
1007         returnValue = true;
1008       if (phValue)
1009         phValue->clear();
1010       RegCloseKey(hKey);
1011     }
1012   }
1013   return returnValue;
1014 #endif // _WIN32
1015 }
1016 
1017 // Find the most recent version of Universal CRT or Windows 10 SDK.
1018 // vcvarsqueryregistry.bat from Visual Studio 2015 sorts entries in the include
1019 // directory by name and uses the last one of the list.
1020 // So we compare entry names lexicographically to find the greatest one.
1021 static bool getWindows10SDKVersionFromPath(llvm::vfs::FileSystem &VFS,
1022                                            const std::string &SDKPath,
1023                                            std::string &SDKVersion) {
1024   llvm::SmallString<128> IncludePath(SDKPath);
1025   llvm::sys::path::append(IncludePath, "Include");
1026   SDKVersion = getHighestNumericTupleInDirectory(VFS, IncludePath);
1027   return !SDKVersion.empty();
1028 }
1029 
1030 static bool getWindowsSDKDirViaCommandLine(llvm::vfs::FileSystem &VFS,
1031                                            const ArgList &Args,
1032                                            std::string &Path, int &Major,
1033                                            std::string &Version) {
1034   if (Arg *A = Args.getLastArg(options::OPT__SLASH_winsdkdir,
1035                                options::OPT__SLASH_winsysroot)) {
1036     // Don't validate the input; trust the value supplied by the user.
1037     // The motivation is to prevent unnecessary file and registry access.
1038     llvm::VersionTuple SDKVersion;
1039     if (Arg *A = Args.getLastArg(options::OPT__SLASH_winsdkversion))
1040       SDKVersion.tryParse(A->getValue());
1041 
1042     if (A->getOption().getID() == options::OPT__SLASH_winsysroot) {
1043       llvm::SmallString<128> SDKPath(A->getValue());
1044       llvm::sys::path::append(SDKPath, "Windows Kits");
1045       if (!SDKVersion.empty())
1046         llvm::sys::path::append(SDKPath, Twine(SDKVersion.getMajor()));
1047       else
1048         llvm::sys::path::append(
1049             SDKPath, getHighestNumericTupleInDirectory(VFS, SDKPath));
1050       Path = std::string(SDKPath.str());
1051     } else {
1052       Path = A->getValue();
1053     }
1054 
1055     if (!SDKVersion.empty()) {
1056       Major = SDKVersion.getMajor();
1057       Version = SDKVersion.getAsString();
1058     } else if (getWindows10SDKVersionFromPath(VFS, Path, Version)) {
1059       Major = 10;
1060     }
1061     return true;
1062   }
1063   return false;
1064 }
1065 
1066 /// Get Windows SDK installation directory.
1067 static bool getWindowsSDKDir(llvm::vfs::FileSystem &VFS, const ArgList &Args,
1068                              std::string &Path, int &Major,
1069                              std::string &WindowsSDKIncludeVersion,
1070                              std::string &WindowsSDKLibVersion) {
1071   // Trust /winsdkdir and /winsdkversion if present.
1072   if (getWindowsSDKDirViaCommandLine(VFS, Args, Path, Major,
1073                                      WindowsSDKIncludeVersion)) {
1074     WindowsSDKLibVersion = WindowsSDKIncludeVersion;
1075     return true;
1076   }
1077 
1078   // FIXME: Try env vars (%WindowsSdkDir%, %UCRTVersion%) before going to registry.
1079 
1080   // Try the Windows registry.
1081   std::string RegistrySDKVersion;
1082   if (!getSystemRegistryString(
1083           "SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\$VERSION",
1084           "InstallationFolder", Path, &RegistrySDKVersion))
1085     return false;
1086   if (Path.empty() || RegistrySDKVersion.empty())
1087     return false;
1088 
1089   WindowsSDKIncludeVersion.clear();
1090   WindowsSDKLibVersion.clear();
1091   Major = 0;
1092   std::sscanf(RegistrySDKVersion.c_str(), "v%d.", &Major);
1093   if (Major <= 7)
1094     return true;
1095   if (Major == 8) {
1096     // Windows SDK 8.x installs libraries in a folder whose names depend on the
1097     // version of the OS you're targeting.  By default choose the newest, which
1098     // usually corresponds to the version of the OS you've installed the SDK on.
1099     const char *Tests[] = {"winv6.3", "win8", "win7"};
1100     for (const char *Test : Tests) {
1101       llvm::SmallString<128> TestPath(Path);
1102       llvm::sys::path::append(TestPath, "Lib", Test);
1103       if (VFS.exists(TestPath)) {
1104         WindowsSDKLibVersion = Test;
1105         break;
1106       }
1107     }
1108     return !WindowsSDKLibVersion.empty();
1109   }
1110   if (Major == 10) {
1111     if (!getWindows10SDKVersionFromPath(VFS, Path, WindowsSDKIncludeVersion))
1112       return false;
1113     WindowsSDKLibVersion = WindowsSDKIncludeVersion;
1114     return true;
1115   }
1116   // Unsupported SDK version
1117   return false;
1118 }
1119 
1120 // Gets the library path required to link against the Windows SDK.
1121 bool MSVCToolChain::getWindowsSDKLibraryPath(
1122     const ArgList &Args, std::string &path) const {
1123   std::string sdkPath;
1124   int sdkMajor = 0;
1125   std::string windowsSDKIncludeVersion;
1126   std::string windowsSDKLibVersion;
1127 
1128   path.clear();
1129   if (!getWindowsSDKDir(getVFS(), Args, sdkPath, sdkMajor,
1130                         windowsSDKIncludeVersion, windowsSDKLibVersion))
1131     return false;
1132 
1133   llvm::SmallString<128> libPath(sdkPath);
1134   llvm::sys::path::append(libPath, "Lib");
1135   if (sdkMajor >= 8) {
1136     llvm::sys::path::append(libPath, windowsSDKLibVersion, "um",
1137                             llvmArchToWindowsSDKArch(getArch()));
1138   } else {
1139     switch (getArch()) {
1140     // In Windows SDK 7.x, x86 libraries are directly in the Lib folder.
1141     case llvm::Triple::x86:
1142       break;
1143     case llvm::Triple::x86_64:
1144       llvm::sys::path::append(libPath, "x64");
1145       break;
1146     case llvm::Triple::arm:
1147       // It is not necessary to link against Windows SDK 7.x when targeting ARM.
1148       return false;
1149     default:
1150       return false;
1151     }
1152   }
1153 
1154   path = std::string(libPath.str());
1155   return true;
1156 }
1157 
1158 // Check if the Include path of a specified version of Visual Studio contains
1159 // specific header files. If not, they are probably shipped with Universal CRT.
1160 bool MSVCToolChain::useUniversalCRT() const {
1161   llvm::SmallString<128> TestPath(
1162       getSubDirectoryPath(SubDirectoryType::Include));
1163   llvm::sys::path::append(TestPath, "stdlib.h");
1164   return !getVFS().exists(TestPath);
1165 }
1166 
1167 static bool getUniversalCRTSdkDir(llvm::vfs::FileSystem &VFS,
1168                                   const ArgList &Args, std::string &Path,
1169                                   std::string &UCRTVersion) {
1170   // If /winsdkdir is passed, use it as location for the UCRT too.
1171   // FIXME: Should there be a dedicated /ucrtdir to override /winsdkdir?
1172   int Major;
1173   if (getWindowsSDKDirViaCommandLine(VFS, Args, Path, Major, UCRTVersion))
1174     return true;
1175 
1176   // FIXME: Try env vars (%UniversalCRTSdkDir%, %UCRTVersion%) before going to
1177   // registry.
1178 
1179   // vcvarsqueryregistry.bat for Visual Studio 2015 queries the registry
1180   // for the specific key "KitsRoot10". So do we.
1181   if (!getSystemRegistryString(
1182           "SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots", "KitsRoot10",
1183           Path, nullptr))
1184     return false;
1185 
1186   return getWindows10SDKVersionFromPath(VFS, Path, UCRTVersion);
1187 }
1188 
1189 bool MSVCToolChain::getUniversalCRTLibraryPath(const ArgList &Args,
1190                                                std::string &Path) const {
1191   std::string UniversalCRTSdkPath;
1192   std::string UCRTVersion;
1193 
1194   Path.clear();
1195   if (!getUniversalCRTSdkDir(getVFS(), Args, UniversalCRTSdkPath, UCRTVersion))
1196     return false;
1197 
1198   StringRef ArchName = llvmArchToWindowsSDKArch(getArch());
1199   if (ArchName.empty())
1200     return false;
1201 
1202   llvm::SmallString<128> LibPath(UniversalCRTSdkPath);
1203   llvm::sys::path::append(LibPath, "Lib", UCRTVersion, "ucrt", ArchName);
1204 
1205   Path = std::string(LibPath.str());
1206   return true;
1207 }
1208 
1209 static VersionTuple getMSVCVersionFromExe(const std::string &BinDir) {
1210   VersionTuple Version;
1211 #ifdef _WIN32
1212   SmallString<128> ClExe(BinDir);
1213   llvm::sys::path::append(ClExe, "cl.exe");
1214 
1215   std::wstring ClExeWide;
1216   if (!llvm::ConvertUTF8toWide(ClExe.c_str(), ClExeWide))
1217     return Version;
1218 
1219   const DWORD VersionSize = ::GetFileVersionInfoSizeW(ClExeWide.c_str(),
1220                                                       nullptr);
1221   if (VersionSize == 0)
1222     return Version;
1223 
1224   SmallVector<uint8_t, 4 * 1024> VersionBlock(VersionSize);
1225   if (!::GetFileVersionInfoW(ClExeWide.c_str(), 0, VersionSize,
1226                              VersionBlock.data()))
1227     return Version;
1228 
1229   VS_FIXEDFILEINFO *FileInfo = nullptr;
1230   UINT FileInfoSize = 0;
1231   if (!::VerQueryValueW(VersionBlock.data(), L"\\",
1232                         reinterpret_cast<LPVOID *>(&FileInfo), &FileInfoSize) ||
1233       FileInfoSize < sizeof(*FileInfo))
1234     return Version;
1235 
1236   const unsigned Major = (FileInfo->dwFileVersionMS >> 16) & 0xFFFF;
1237   const unsigned Minor = (FileInfo->dwFileVersionMS      ) & 0xFFFF;
1238   const unsigned Micro = (FileInfo->dwFileVersionLS >> 16) & 0xFFFF;
1239 
1240   Version = VersionTuple(Major, Minor, Micro);
1241 #endif
1242   return Version;
1243 }
1244 
1245 void MSVCToolChain::AddSystemIncludeWithSubfolder(
1246     const ArgList &DriverArgs, ArgStringList &CC1Args,
1247     const std::string &folder, const Twine &subfolder1, const Twine &subfolder2,
1248     const Twine &subfolder3) const {
1249   llvm::SmallString<128> path(folder);
1250   llvm::sys::path::append(path, subfolder1, subfolder2, subfolder3);
1251   addSystemInclude(DriverArgs, CC1Args, path);
1252 }
1253 
1254 void MSVCToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
1255                                               ArgStringList &CC1Args) const {
1256   if (DriverArgs.hasArg(options::OPT_nostdinc))
1257     return;
1258 
1259   if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
1260     AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, getDriver().ResourceDir,
1261                                   "include");
1262   }
1263 
1264   // Add %INCLUDE%-like directories from the -imsvc flag.
1265   for (const auto &Path : DriverArgs.getAllArgValues(options::OPT__SLASH_imsvc))
1266     addSystemInclude(DriverArgs, CC1Args, Path);
1267 
1268   auto AddSystemIncludesFromEnv = [&](StringRef Var) -> bool {
1269     if (auto Val = llvm::sys::Process::GetEnv(Var)) {
1270       SmallVector<StringRef, 8> Dirs;
1271       StringRef(*Val).split(Dirs, ";", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
1272       if (!Dirs.empty()) {
1273         addSystemIncludes(DriverArgs, CC1Args, Dirs);
1274         return true;
1275       }
1276     }
1277     return false;
1278   };
1279 
1280   // Add %INCLUDE%-like dirs via /external:env: flags.
1281   for (const auto &Var :
1282        DriverArgs.getAllArgValues(options::OPT__SLASH_external_env)) {
1283     AddSystemIncludesFromEnv(Var);
1284   }
1285 
1286   // Add DIA SDK include if requested.
1287   if (const Arg *A = DriverArgs.getLastArg(options::OPT__SLASH_diasdkdir,
1288                                            options::OPT__SLASH_winsysroot)) {
1289     // cl.exe doesn't find the DIA SDK automatically, so this too requires
1290     // explicit flags and doesn't automatically look in "DIA SDK" relative
1291     // to the path we found for VCToolChainPath.
1292     llvm::SmallString<128> DIASDKPath(A->getValue());
1293     if (A->getOption().getID() == options::OPT__SLASH_winsysroot)
1294       llvm::sys::path::append(DIASDKPath, "DIA SDK");
1295     AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, std::string(DIASDKPath),
1296                                   "include");
1297   }
1298 
1299   if (DriverArgs.hasArg(options::OPT_nostdlibinc))
1300     return;
1301 
1302   // Honor %INCLUDE% and %EXTERNAL_INCLUDE%. It should have essential search
1303   // paths set by vcvarsall.bat. Skip if the user expressly set a vctoolsdir.
1304   if (!DriverArgs.getLastArg(options::OPT__SLASH_vctoolsdir,
1305                              options::OPT__SLASH_winsysroot)) {
1306     bool Found = AddSystemIncludesFromEnv("INCLUDE");
1307     Found |= AddSystemIncludesFromEnv("EXTERNAL_INCLUDE");
1308     if (Found)
1309       return;
1310   }
1311 
1312   // When built with access to the proper Windows APIs, try to actually find
1313   // the correct include paths first.
1314   if (!VCToolChainPath.empty()) {
1315     addSystemInclude(DriverArgs, CC1Args,
1316                      getSubDirectoryPath(SubDirectoryType::Include));
1317     addSystemInclude(DriverArgs, CC1Args,
1318                      getSubDirectoryPath(SubDirectoryType::Include, "atlmfc"));
1319 
1320     if (useUniversalCRT()) {
1321       std::string UniversalCRTSdkPath;
1322       std::string UCRTVersion;
1323       if (getUniversalCRTSdkDir(getVFS(), DriverArgs, UniversalCRTSdkPath,
1324                                 UCRTVersion)) {
1325         AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, UniversalCRTSdkPath,
1326                                       "Include", UCRTVersion, "ucrt");
1327       }
1328     }
1329 
1330     std::string WindowsSDKDir;
1331     int major = 0;
1332     std::string windowsSDKIncludeVersion;
1333     std::string windowsSDKLibVersion;
1334     if (getWindowsSDKDir(getVFS(), DriverArgs, WindowsSDKDir, major,
1335                          windowsSDKIncludeVersion, windowsSDKLibVersion)) {
1336       if (major >= 8) {
1337         // Note: windowsSDKIncludeVersion is empty for SDKs prior to v10.
1338         // Anyway, llvm::sys::path::append is able to manage it.
1339         AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
1340                                       "Include", windowsSDKIncludeVersion,
1341                                       "shared");
1342         AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
1343                                       "Include", windowsSDKIncludeVersion,
1344                                       "um");
1345         AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
1346                                       "Include", windowsSDKIncludeVersion,
1347                                       "winrt");
1348         if (major >= 10) {
1349           llvm::VersionTuple Tuple;
1350           if (!Tuple.tryParse(windowsSDKIncludeVersion) &&
1351               Tuple.getSubminor().getValueOr(0) >= 17134) {
1352             AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
1353                                           "Include", windowsSDKIncludeVersion,
1354                                           "cppwinrt");
1355           }
1356         }
1357       } else {
1358         AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
1359                                       "Include");
1360       }
1361     }
1362 
1363     return;
1364   }
1365 
1366 #if defined(_WIN32)
1367   // As a fallback, select default install paths.
1368   // FIXME: Don't guess drives and paths like this on Windows.
1369   const StringRef Paths[] = {
1370     "C:/Program Files/Microsoft Visual Studio 10.0/VC/include",
1371     "C:/Program Files/Microsoft Visual Studio 9.0/VC/include",
1372     "C:/Program Files/Microsoft Visual Studio 9.0/VC/PlatformSDK/Include",
1373     "C:/Program Files/Microsoft Visual Studio 8/VC/include",
1374     "C:/Program Files/Microsoft Visual Studio 8/VC/PlatformSDK/Include"
1375   };
1376   addSystemIncludes(DriverArgs, CC1Args, Paths);
1377 #endif
1378 }
1379 
1380 void MSVCToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
1381                                                  ArgStringList &CC1Args) const {
1382   // FIXME: There should probably be logic here to find libc++ on Windows.
1383 }
1384 
1385 VersionTuple MSVCToolChain::computeMSVCVersion(const Driver *D,
1386                                                const ArgList &Args) const {
1387   bool IsWindowsMSVC = getTriple().isWindowsMSVCEnvironment();
1388   VersionTuple MSVT = ToolChain::computeMSVCVersion(D, Args);
1389   if (MSVT.empty())
1390     MSVT = getTriple().getEnvironmentVersion();
1391   if (MSVT.empty() && IsWindowsMSVC)
1392     MSVT = getMSVCVersionFromExe(getSubDirectoryPath(SubDirectoryType::Bin));
1393   if (MSVT.empty() &&
1394       Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions,
1395                    IsWindowsMSVC)) {
1396     // -fms-compatibility-version=19.20 is default, aka 2019, 16.x
1397     MSVT = VersionTuple(19, 20);
1398   }
1399   return MSVT;
1400 }
1401 
1402 std::string
1403 MSVCToolChain::ComputeEffectiveClangTriple(const ArgList &Args,
1404                                            types::ID InputType) const {
1405   // The MSVC version doesn't care about the architecture, even though it
1406   // may look at the triple internally.
1407   VersionTuple MSVT = computeMSVCVersion(/*D=*/nullptr, Args);
1408   MSVT = VersionTuple(MSVT.getMajor(), MSVT.getMinor().getValueOr(0),
1409                       MSVT.getSubminor().getValueOr(0));
1410 
1411   // For the rest of the triple, however, a computed architecture name may
1412   // be needed.
1413   llvm::Triple Triple(ToolChain::ComputeEffectiveClangTriple(Args, InputType));
1414   if (Triple.getEnvironment() == llvm::Triple::MSVC) {
1415     StringRef ObjFmt = Triple.getEnvironmentName().split('-').second;
1416     if (ObjFmt.empty())
1417       Triple.setEnvironmentName((Twine("msvc") + MSVT.getAsString()).str());
1418     else
1419       Triple.setEnvironmentName(
1420           (Twine("msvc") + MSVT.getAsString() + Twine('-') + ObjFmt).str());
1421   }
1422   return Triple.getTriple();
1423 }
1424 
1425 SanitizerMask MSVCToolChain::getSupportedSanitizers() const {
1426   SanitizerMask Res = ToolChain::getSupportedSanitizers();
1427   Res |= SanitizerKind::Address;
1428   Res |= SanitizerKind::PointerCompare;
1429   Res |= SanitizerKind::PointerSubtract;
1430   Res |= SanitizerKind::Fuzzer;
1431   Res |= SanitizerKind::FuzzerNoLink;
1432   Res &= ~SanitizerKind::CFIMFCall;
1433   return Res;
1434 }
1435 
1436 static void TranslateOptArg(Arg *A, llvm::opt::DerivedArgList &DAL,
1437                             bool SupportsForcingFramePointer,
1438                             const char *ExpandChar, const OptTable &Opts) {
1439   assert(A->getOption().matches(options::OPT__SLASH_O));
1440 
1441   StringRef OptStr = A->getValue();
1442   for (size_t I = 0, E = OptStr.size(); I != E; ++I) {
1443     const char &OptChar = *(OptStr.data() + I);
1444     switch (OptChar) {
1445     default:
1446       break;
1447     case '1':
1448     case '2':
1449     case 'x':
1450     case 'd':
1451       // Ignore /O[12xd] flags that aren't the last one on the command line.
1452       // Only the last one gets expanded.
1453       if (&OptChar != ExpandChar) {
1454         A->claim();
1455         break;
1456       }
1457       if (OptChar == 'd') {
1458         DAL.AddFlagArg(A, Opts.getOption(options::OPT_O0));
1459       } else {
1460         if (OptChar == '1') {
1461           DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "s");
1462         } else if (OptChar == '2' || OptChar == 'x') {
1463           DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
1464           DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "2");
1465         }
1466         if (SupportsForcingFramePointer &&
1467             !DAL.hasArgNoClaim(options::OPT_fno_omit_frame_pointer))
1468           DAL.AddFlagArg(A, Opts.getOption(options::OPT_fomit_frame_pointer));
1469         if (OptChar == '1' || OptChar == '2')
1470           DAL.AddFlagArg(A, Opts.getOption(options::OPT_ffunction_sections));
1471       }
1472       break;
1473     case 'b':
1474       if (I + 1 != E && isdigit(OptStr[I + 1])) {
1475         switch (OptStr[I + 1]) {
1476         case '0':
1477           DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_inline));
1478           break;
1479         case '1':
1480           DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_hint_functions));
1481           break;
1482         case '2':
1483           DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_functions));
1484           break;
1485         }
1486         ++I;
1487       }
1488       break;
1489     case 'g':
1490       A->claim();
1491       break;
1492     case 'i':
1493       if (I + 1 != E && OptStr[I + 1] == '-') {
1494         ++I;
1495         DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_builtin));
1496       } else {
1497         DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
1498       }
1499       break;
1500     case 's':
1501       DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "s");
1502       break;
1503     case 't':
1504       DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "2");
1505       break;
1506     case 'y': {
1507       bool OmitFramePointer = true;
1508       if (I + 1 != E && OptStr[I + 1] == '-') {
1509         OmitFramePointer = false;
1510         ++I;
1511       }
1512       if (SupportsForcingFramePointer) {
1513         if (OmitFramePointer)
1514           DAL.AddFlagArg(A,
1515                          Opts.getOption(options::OPT_fomit_frame_pointer));
1516         else
1517           DAL.AddFlagArg(
1518               A, Opts.getOption(options::OPT_fno_omit_frame_pointer));
1519       } else {
1520         // Don't warn about /Oy- in x86-64 builds (where
1521         // SupportsForcingFramePointer is false).  The flag having no effect
1522         // there is a compiler-internal optimization, and people shouldn't have
1523         // to special-case their build files for x86-64 clang-cl.
1524         A->claim();
1525       }
1526       break;
1527     }
1528     }
1529   }
1530 }
1531 
1532 static void TranslateDArg(Arg *A, llvm::opt::DerivedArgList &DAL,
1533                           const OptTable &Opts) {
1534   assert(A->getOption().matches(options::OPT_D));
1535 
1536   StringRef Val = A->getValue();
1537   size_t Hash = Val.find('#');
1538   if (Hash == StringRef::npos || Hash > Val.find('=')) {
1539     DAL.append(A);
1540     return;
1541   }
1542 
1543   std::string NewVal = std::string(Val);
1544   NewVal[Hash] = '=';
1545   DAL.AddJoinedArg(A, Opts.getOption(options::OPT_D), NewVal);
1546 }
1547 
1548 static void TranslatePermissive(Arg *A, llvm::opt::DerivedArgList &DAL,
1549                                 const OptTable &Opts) {
1550   DAL.AddFlagArg(A, Opts.getOption(options::OPT__SLASH_Zc_twoPhase_));
1551   DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_operator_names));
1552 }
1553 
1554 static void TranslatePermissiveMinus(Arg *A, llvm::opt::DerivedArgList &DAL,
1555                                      const OptTable &Opts) {
1556   DAL.AddFlagArg(A, Opts.getOption(options::OPT__SLASH_Zc_twoPhase));
1557   DAL.AddFlagArg(A, Opts.getOption(options::OPT_foperator_names));
1558 }
1559 
1560 llvm::opt::DerivedArgList *
1561 MSVCToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args,
1562                              StringRef BoundArch,
1563                              Action::OffloadKind OFK) const {
1564   DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
1565   const OptTable &Opts = getDriver().getOpts();
1566 
1567   // /Oy and /Oy- don't have an effect on X86-64
1568   bool SupportsForcingFramePointer = getArch() != llvm::Triple::x86_64;
1569 
1570   // The -O[12xd] flag actually expands to several flags.  We must desugar the
1571   // flags so that options embedded can be negated.  For example, the '-O2' flag
1572   // enables '-Oy'.  Expanding '-O2' into its constituent flags allows us to
1573   // correctly handle '-O2 -Oy-' where the trailing '-Oy-' disables a single
1574   // aspect of '-O2'.
1575   //
1576   // Note that this expansion logic only applies to the *last* of '[12xd]'.
1577 
1578   // First step is to search for the character we'd like to expand.
1579   const char *ExpandChar = nullptr;
1580   for (Arg *A : Args.filtered(options::OPT__SLASH_O)) {
1581     StringRef OptStr = A->getValue();
1582     for (size_t I = 0, E = OptStr.size(); I != E; ++I) {
1583       char OptChar = OptStr[I];
1584       char PrevChar = I > 0 ? OptStr[I - 1] : '0';
1585       if (PrevChar == 'b') {
1586         // OptChar does not expand; it's an argument to the previous char.
1587         continue;
1588       }
1589       if (OptChar == '1' || OptChar == '2' || OptChar == 'x' || OptChar == 'd')
1590         ExpandChar = OptStr.data() + I;
1591     }
1592   }
1593 
1594   for (Arg *A : Args) {
1595     if (A->getOption().matches(options::OPT__SLASH_O)) {
1596       // The -O flag actually takes an amalgam of other options.  For example,
1597       // '/Ogyb2' is equivalent to '/Og' '/Oy' '/Ob2'.
1598       TranslateOptArg(A, *DAL, SupportsForcingFramePointer, ExpandChar, Opts);
1599     } else if (A->getOption().matches(options::OPT_D)) {
1600       // Translate -Dfoo#bar into -Dfoo=bar.
1601       TranslateDArg(A, *DAL, Opts);
1602     } else if (A->getOption().matches(options::OPT__SLASH_permissive)) {
1603       // Expand /permissive
1604       TranslatePermissive(A, *DAL, Opts);
1605     } else if (A->getOption().matches(options::OPT__SLASH_permissive_)) {
1606       // Expand /permissive-
1607       TranslatePermissiveMinus(A, *DAL, Opts);
1608     } else if (OFK != Action::OFK_HIP) {
1609       // HIP Toolchain translates input args by itself.
1610       DAL->append(A);
1611     }
1612   }
1613 
1614   return DAL;
1615 }
1616 
1617 void MSVCToolChain::addClangTargetOptions(
1618     const ArgList &DriverArgs, ArgStringList &CC1Args,
1619     Action::OffloadKind DeviceOffloadKind) const {
1620   // MSVC STL kindly allows removing all usages of typeid by defining
1621   // _HAS_STATIC_RTTI to 0. Do so, when compiling with -fno-rtti
1622   if (DriverArgs.hasArg(options::OPT_fno_rtti, options::OPT_frtti,
1623                         /*Default=*/false))
1624     CC1Args.push_back("-D_HAS_STATIC_RTTI=0");
1625 }
1626