14 #include "clang/Config/config.h"
20 #include "llvm/ADT/StringExtras.h"
21 #include "llvm/Option/Arg.h"
22 #include "llvm/Option/ArgList.h"
23 #include "llvm/Support/ConvertUTF.h"
24 #include "llvm/Support/ErrorHandling.h"
25 #include "llvm/Support/FileSystem.h"
26 #include "llvm/Support/MemoryBuffer.h"
27 #include "llvm/Support/Path.h"
28 #include "llvm/Support/Process.h"
29 #include "llvm/Support/VirtualFileSystem.h"
30 #include "llvm/TargetParser/Host.h"
34 #define WIN32_LEAN_AND_MEAN
45 using namespace clang;
48 static bool canExecute(llvm::vfs::FileSystem &VFS, StringRef Path) {
49 auto Status = VFS.status(Path);
52 return (Status->getPermissions() & llvm::sys::fs::perms::all_exe) != 0;
63 MSVC.getSubDirectoryPath(llvm::SubDirectoryType::Bin));
64 llvm::sys::path::append(FilePath, Exe);
65 return std::string(
canExecute(TC.
getVFS(), FilePath) ? FilePath.str() : Exe);
70 void visualstudio::Linker::constructMSVCLibCommand(
Compilation &C,
74 const ArgList &Args)
const {
75 ArgStringList CmdArgs;
76 for (
const auto &II : Input) {
77 if (II.getType() == types::TY_Tempfilelist) {
79 std::string
FileName(II.getFilename());
80 const char *ArgFile = Args.MakeArgString(
"@" + FileName);
81 CmdArgs.push_back(ArgFile);
84 CmdArgs.push_back(II.getFilename());
86 if (Args.hasArg(options::OPT_fsycl_link_EQ) &&
87 Args.hasArg(options::OPT_fintelfpga))
88 CmdArgs.push_back(
"/IGNORE:4221");
91 if (Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl,
false))
92 CmdArgs.push_back(
"/IGNORE:4078");
95 C.getArgs().MakeArgString(Twine(
"-OUT:") + Output.
getFilename()));
98 const char *Exec =
C.getArgs().MakeArgString(ExecPath);
99 C.addCommand(std::make_unique<Command>(
107 const char *LinkingOutput)
const {
108 ArgStringList CmdArgs;
111 if (Args.hasArg(options::OPT_fsycl_link_EQ) &&
112 JA.
getType() == types::TY_Archive) {
113 constructMSVCLibCommand(C, JA, Output, Inputs, Args);
122 Args.MakeArgString(std::string(
"-out:") + Output.
getFilename()));
124 if (Args.hasArg(options::OPT_marm64x))
125 CmdArgs.push_back(
"-machine:arm64x");
126 else if (TC.getTriple().isWindowsArm64EC())
127 CmdArgs.push_back(
"-machine:arm64ec");
129 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles) &&
130 !C.getDriver().IsCLMode() && !C.getDriver().IsFlangMode()) {
131 if (Args.hasArg(options::OPT_fsycl) && !Args.hasArg(options::OPT_nolibsycl))
132 CmdArgs.push_back(
"-defaultlib:msvcrt");
134 CmdArgs.push_back(
"-defaultlib:libcmt");
135 CmdArgs.push_back(
"-defaultlib:oldnames");
138 if ((!C.getDriver().IsCLMode() && Args.hasArg(options::OPT_fsycl) &&
139 !Args.hasArg(options::OPT_nolibsycl)) ||
140 Args.hasArg(options::OPT_fsycl_host_compiler_EQ)) {
141 CmdArgs.push_back(Args.MakeArgString(std::string(
"-libpath:") +
142 TC.getDriver().Dir +
"/../lib"));
146 if (Args.hasArg(options::OPT_fpreview_breaking_changes))
147 CmdArgs.push_back(
"-defaultlib:sycl" SYCL_MAJOR_VERSION
"-preview.lib");
149 CmdArgs.push_back(
"-defaultlib:sycl" SYCL_MAJOR_VERSION
".lib");
151 CmdArgs.push_back(
"-defaultlib:sycl-devicelib-host.lib");
155 if (Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl,
false))
156 CmdArgs.push_back(
"/IGNORE:4078");
163 if (
const Arg *A = Args.getLastArg(options::OPT__SLASH_diasdkdir,
164 options::OPT__SLASH_winsysroot)) {
169 if (A->getOption().getID() == options::OPT__SLASH_winsysroot)
170 llvm::sys::path::append(DIAPath,
"DIA SDK");
173 llvm::sys::path::append(DIAPath,
"lib",
174 llvm::archToLegacyVCArch(TC.getArch()));
175 CmdArgs.push_back(Args.MakeArgString(Twine(
"-libpath:") + DIAPath));
177 if (!llvm::sys::Process::GetEnv(
"LIB") ||
178 Args.getLastArg(options::OPT__SLASH_vctoolsdir,
179 options::OPT__SLASH_winsysroot)) {
180 CmdArgs.push_back(Args.MakeArgString(
182 TC.getSubDirectoryPath(llvm::SubDirectoryType::Lib)));
183 CmdArgs.push_back(Args.MakeArgString(
185 TC.getSubDirectoryPath(llvm::SubDirectoryType::Lib,
"atlmfc")));
187 if (!llvm::sys::Process::GetEnv(
"LIB") ||
188 Args.getLastArg(options::OPT__SLASH_winsdkdir,
189 options::OPT__SLASH_winsysroot)) {
190 if (TC.useUniversalCRT()) {
191 std::string UniversalCRTLibPath;
192 if (TC.getUniversalCRTLibraryPath(Args, UniversalCRTLibPath))
194 Args.MakeArgString(Twine(
"-libpath:") + UniversalCRTLibPath));
196 std::string WindowsSdkLibPath;
197 if (TC.getWindowsSDKLibraryPath(Args, WindowsSdkLibPath))
199 Args.MakeArgString(std::string(
"-libpath:") + WindowsSdkLibPath));
202 if (!C.getDriver().IsCLMode() && Args.hasArg(options::OPT_L))
203 for (
const auto &LibPath : Args.getAllArgValues(options::OPT_L))
204 CmdArgs.push_back(Args.MakeArgString(
"-libpath:" + LibPath));
206 if (C.getDriver().IsFlangMode()) {
213 CmdArgs.push_back(
"/subsystem:console");
218 for (
const auto &LibPath : TC.getLibraryPaths()) {
219 if (TC.getVFS().exists(LibPath))
220 CmdArgs.push_back(Args.MakeArgString(
"-libpath:" + LibPath));
222 auto CRTPath = TC.getCompilerRTPath();
223 if (TC.getVFS().exists(CRTPath))
224 CmdArgs.push_back(Args.MakeArgString(
"-libpath:" + CRTPath));
226 CmdArgs.push_back(
"-nologo");
228 if (Args.hasArg(options::OPT_g_Group, options::OPT__SLASH_Z7))
229 CmdArgs.push_back(
"-debug");
233 if (Args.hasArg(options::OPT_fms_hotpatch, options::OPT__SLASH_hotpatch))
234 CmdArgs.push_back(
"-functionpadmin");
238 bool DefaultIncrementalLinkerCompatible =
239 C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment();
240 if (!Args.hasFlag(options::OPT_mincremental_linker_compatible,
241 options::OPT_mno_incremental_linker_compatible,
242 DefaultIncrementalLinkerCompatible))
243 CmdArgs.push_back(
"-Brepro");
245 bool DLL = Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd,
246 options::OPT_shared);
248 CmdArgs.push_back(Args.MakeArgString(
"-dll"));
251 llvm::sys::path::replace_extension(ImplibName,
"lib");
252 CmdArgs.push_back(Args.MakeArgString(std::string(
"-implib:") + ImplibName));
255 if (TC.getSanitizerArgs(Args).needsFuzzer()) {
256 if (!Args.hasArg(options::OPT_shared))
258 Args.MakeArgString(std::string(
"-wholearchive:") +
259 TC.getCompilerRTArgString(Args,
"fuzzer")));
260 CmdArgs.push_back(Args.MakeArgString(
"-debug"));
263 CmdArgs.push_back(Args.MakeArgString(
"-incremental:no"));
266 if (TC.getSanitizerArgs(Args).needsAsanRt()) {
267 CmdArgs.push_back(Args.MakeArgString(
"-debug"));
268 CmdArgs.push_back(Args.MakeArgString(
"-incremental:no"));
269 if (TC.getSanitizerArgs(Args).needsSharedRt() ||
270 Args.hasArg(options::OPT__SLASH_MD, options::OPT__SLASH_MDd)) {
271 for (
const auto &Lib : {
"asan_dynamic",
"asan_dynamic_runtime_thunk"})
272 CmdArgs.push_back(TC.getCompilerRTArgString(Args, Lib));
275 CmdArgs.push_back(Args.MakeArgString(
276 TC.getArch() == llvm::Triple::x86
277 ?
"-include:___asan_seh_interceptor"
278 :
"-include:__asan_seh_interceptor"));
281 CmdArgs.push_back(Args.MakeArgString(std::string(
"-wholearchive:") +
282 TC.getCompilerRT(Args,
"asan_dynamic_runtime_thunk")));
284 CmdArgs.push_back(TC.getCompilerRTArgString(Args,
"asan_dll_thunk"));
286 for (
const auto &Lib : {
"asan",
"asan_cxx"}) {
287 CmdArgs.push_back(TC.getCompilerRTArgString(Args, Lib));
291 CmdArgs.push_back(Args.MakeArgString(std::string(
"-wholearchive:") +
292 TC.getCompilerRT(Args, Lib)));
297 Args.AddAllArgValues(CmdArgs, options::OPT__SLASH_link);
305 Args.MakeArgString(std::string(
"-out:") + Output.
getFilename()));
308 for (
const Arg *A : Args.filtered(options::OPT__SLASH_guard)) {
309 StringRef GuardArgs = A->getValue();
310 if (GuardArgs.equals_insensitive(
"cf") ||
311 GuardArgs.equals_insensitive(
"cf,nochecks")) {
313 CmdArgs.push_back(
"-guard:cf");
314 }
else if (GuardArgs.equals_insensitive(
"cf-")) {
315 CmdArgs.push_back(
"-guard:cf-");
316 }
else if (GuardArgs.equals_insensitive(
"ehcont")) {
317 CmdArgs.push_back(
"-guard:ehcont");
318 }
else if (GuardArgs.equals_insensitive(
"ehcont-")) {
319 CmdArgs.push_back(
"-guard:ehcont-");
323 if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
324 options::OPT_fno_openmp,
false)) {
325 CmdArgs.push_back(
"-nodefaultlib:vcomp.lib");
326 CmdArgs.push_back(
"-nodefaultlib:vcompd.lib");
327 CmdArgs.push_back(Args.MakeArgString(std::string(
"-libpath:") +
328 TC.getDriver().Dir +
"/../lib"));
329 switch (TC.getDriver().getOpenMPRuntime(Args)) {
331 CmdArgs.push_back(
"-defaultlib:libomp.lib");
334 CmdArgs.push_back(
"-defaultlib:libiomp5md.lib");
346 if (!Args.hasArg(options::OPT_nostdlib)) {
351 Args.getLastArgValue(options::OPT_fuse_ld_EQ, CLANG_DEFAULT_LINKER);
355 else if (
Linker.equals_insensitive(
"lld"))
358 if (
Linker ==
"lld-link") {
359 for (Arg *A : Args.filtered(options::OPT_vfsoverlay))
361 Args.MakeArgString(std::string(
"/vfsoverlay:") + A->getValue()));
363 if (C.getDriver().isUsingLTO() &&
364 Args.hasFlag(options::OPT_gsplit_dwarf, options::OPT_gno_split_dwarf,
366 CmdArgs.push_back(Args.MakeArgString(Twine(
"/dwodir:") +
371 for (
const auto &Input : Inputs) {
372 if (Input.isFilename()) {
373 if (Input.getType() == types::TY_Tempfilelist) {
375 std::string
FileName(Input.getFilename());
376 const char *ArgFile = Args.MakeArgString(
"@" +
FileName);
377 CmdArgs.push_back(ArgFile);
380 CmdArgs.push_back(Input.getFilename());
384 const Arg &A = Input.getInputArg();
387 if (A.getOption().matches(options::OPT_l)) {
388 StringRef Lib = A.getValue();
389 const char *LinkLibArg;
390 if (Lib.ends_with(
".lib"))
391 LinkLibArg = Args.MakeArgString(Lib);
393 LinkLibArg = Args.MakeArgString(Lib +
".lib");
394 CmdArgs.push_back(LinkLibArg);
400 A.renderAsInput(Args, CmdArgs);
405 TC.addProfileRTLibs(Args, CmdArgs);
407 std::vector<const char *> Environment;
412 if (
Linker.equals_insensitive(
"link")) {
418 if (!TC.FoundMSVCInstall() && !
canExecute(TC.getVFS(), linkPath)) {
420 ClPath = TC.GetProgramPath(
"cl.exe");
422 linkPath = llvm::sys::path::parent_path(ClPath);
423 llvm::sys::path::append(linkPath,
"link.exe");
425 C.getDriver().Diag(clang::diag::warn_drv_msvc_not_found);
427 C.getDriver().Diag(clang::diag::warn_drv_msvc_not_found);
433 if (TC.getSanitizerArgs(Args).needsAsanRt())
434 CmdArgs.push_back(
"/INFERASANLIBS:NO");
443 if (TC.getIsVS2017OrNewer() &&
444 llvm::Triple(llvm::sys::getProcessTriple()).getArch() != TC.getArch()) {
445 auto HostArch = llvm::Triple(llvm::sys::getProcessTriple()).getArch();
448 std::unique_ptr<wchar_t[], decltype(&FreeEnvironmentStringsW)>(
449 GetEnvironmentStringsW(), FreeEnvironmentStringsW);
451 goto SkipSettingEnvironment;
454 size_t EnvBlockLen = 0;
455 while (EnvBlockWide[EnvBlockLen] != L
'\0') {
457 EnvBlockLen += std::wcslen(&EnvBlockWide[EnvBlockLen]) +
462 std::string EnvBlock;
463 if (!llvm::convertUTF16ToUTF8String(
465 EnvBlockLen *
sizeof(EnvBlockWide[0])),
467 goto SkipSettingEnvironment;
469 Environment.reserve(EnvCount);
474 for (
const char *
Cursor = EnvBlock.data(); *
Cursor !=
'\0';) {
475 llvm::StringRef EnvVar(
Cursor);
476 if (EnvVar.starts_with_insensitive(
"path=")) {
477 constexpr
size_t PrefixLen = 5;
478 Environment.push_back(Args.MakeArgString(
479 EnvVar.substr(0, PrefixLen) +
480 TC.getSubDirectoryPath(llvm::SubDirectoryType::Bin) +
481 llvm::Twine(llvm::sys::EnvPathSeparator) +
482 TC.getSubDirectoryPath(llvm::SubDirectoryType::Bin, HostArch) +
483 (EnvVar.size() > PrefixLen
484 ? llvm::Twine(llvm::sys::EnvPathSeparator) +
485 EnvVar.substr(PrefixLen)
488 Environment.push_back(Args.MakeArgString(EnvVar));
490 Cursor += EnvVar.size() + 1 ;
493 SkipSettingEnvironment:;
496 linkPath = TC.GetProgramPath(
Linker.str().c_str());
499 auto LinkCmd = std::make_unique<Command>(
501 Args.MakeArgString(linkPath), CmdArgs, Inputs, Output);
502 if (!Environment.empty())
503 LinkCmd->setEnvironment(Environment);
504 C.addCommand(std::move(LinkCmd));
509 :
ToolChain(D, Triple, Args), CudaInstallation(D, Triple, Args),
510 RocmInstallation(D, Triple, Args) {
513 std::optional<llvm::StringRef> VCToolsDir, VCToolsVersion;
514 if (Arg *A = Args.getLastArg(options::OPT__SLASH_vctoolsdir))
515 VCToolsDir = A->getValue();
516 if (Arg *A = Args.getLastArg(options::OPT__SLASH_vctoolsversion))
517 VCToolsVersion = A->getValue();
518 if (Arg *A = Args.getLastArg(options::OPT__SLASH_winsdkdir))
519 WinSdkDir = A->getValue();
520 if (Arg *A = Args.getLastArg(options::OPT__SLASH_winsdkversion))
521 WinSdkVersion = A->getValue();
522 if (Arg *A = Args.getLastArg(options::OPT__SLASH_winsysroot))
523 WinSysRoot = A->getValue();
529 llvm::findVCToolChainViaCommandLine(
getVFS(), VCToolsDir, VCToolsVersion,
530 WinSysRoot, VCToolChainPath, VSLayout) ||
531 llvm::findVCToolChainViaEnvironment(
getVFS(), VCToolChainPath,
533 llvm::findVCToolChainViaSetupConfig(
getVFS(), VCToolsVersion,
534 VCToolChainPath, VSLayout) ||
535 llvm::findVCToolChainViaRegistry(VCToolChainPath, VSLayout);
558 if (
getArch() == llvm::Triple::x86_64 ||
getArch() == llvm::Triple::arm ||
559 getArch() == llvm::Triple::thumb ||
getArch() == llvm::Triple::aarch64)
566 return getArch() == llvm::Triple::x86_64 ||
567 getArch() == llvm::Triple::aarch64;
575 return getArch() == llvm::Triple::x86_64 ||
576 getArch() == llvm::Triple::aarch64;
580 ArgStringList &CC1Args)
const {
581 CudaInstallation->AddCudaIncludeArgs(DriverArgs, CC1Args);
585 ArgStringList &CC1Args)
const {
586 RocmInstallation->AddHIPIncludeArgs(DriverArgs, CC1Args);
590 ArgStringList &CmdArgs)
const {
591 CmdArgs.append({Args.MakeArgString(StringRef(
"-libpath:") +
592 RocmInstallation->getLibPath()),
597 CudaInstallation->print(OS);
598 RocmInstallation->print(OS);
603 llvm::StringRef SubdirParent)
const {
604 return llvm::getSubDirectoryPath(
Type, VSLayout, VCToolChainPath,
getArch(),
610 llvm::Triple::ArchType TargetArch)
const {
611 return llvm::getSubDirectoryPath(
Type, VSLayout, VCToolChainPath, TargetArch,
621 std::string &path)
const {
624 std::string windowsSDKIncludeVersion;
625 std::string windowsSDKLibVersion;
628 if (!llvm::getWindowsSDKDir(
getVFS(), WinSdkDir, WinSdkVersion, WinSysRoot,
629 sdkPath, sdkMajor, windowsSDKIncludeVersion,
630 windowsSDKLibVersion))
634 llvm::sys::path::append(libPath,
"Lib");
636 if (!(WinSdkDir.has_value() || WinSysRoot.has_value()) &&
637 WinSdkVersion.has_value())
638 windowsSDKLibVersion = *WinSdkVersion;
640 llvm::sys::path::append(libPath, windowsSDKLibVersion,
"um");
641 return llvm::appendArchToWindowsSDKLibPath(sdkMajor, libPath,
getArch(),
646 return llvm::useUniversalCRT(VSLayout, VCToolChainPath,
getArch(),
getVFS());
650 std::string &Path)
const {
651 std::string UniversalCRTSdkPath;
652 std::string UCRTVersion;
655 if (!llvm::getUniversalCRTSdkDir(
getVFS(), WinSdkDir, WinSdkVersion,
656 WinSysRoot, UniversalCRTSdkPath,
660 if (!(WinSdkDir.has_value() || WinSysRoot.has_value()) &&
661 WinSdkVersion.has_value())
662 UCRTVersion = *WinSdkVersion;
664 StringRef ArchName = llvm::archToWindowsSDKArch(
getArch());
665 if (ArchName.empty())
669 llvm::sys::path::append(LibPath,
"Lib", UCRTVersion,
"ucrt", ArchName);
671 Path = std::string(LibPath);
676 VersionTuple Version;
679 llvm::sys::path::append(ClExe,
"cl.exe");
681 std::wstring ClExeWide;
682 if (!llvm::ConvertUTF8toWide(ClExe.c_str(), ClExeWide))
685 const DWORD VersionSize = ::GetFileVersionInfoSizeW(ClExeWide.c_str(),
687 if (VersionSize == 0)
691 if (!::GetFileVersionInfoW(ClExeWide.c_str(), 0, VersionSize,
692 VersionBlock.data()))
695 VS_FIXEDFILEINFO *FileInfo =
nullptr;
696 UINT FileInfoSize = 0;
697 if (!::VerQueryValueW(VersionBlock.data(), L
"\\",
698 reinterpret_cast<LPVOID *
>(&FileInfo), &FileInfoSize) ||
699 FileInfoSize <
sizeof(*FileInfo))
702 const unsigned Major = (FileInfo->dwFileVersionMS >> 16) & 0xFFFF;
703 const unsigned Minor = (FileInfo->dwFileVersionMS ) & 0xFFFF;
704 const unsigned Micro = (FileInfo->dwFileVersionLS >> 16) & 0xFFFF;
706 Version = VersionTuple(Major, Minor, Micro);
712 const ArgList &DriverArgs, ArgStringList &CC1Args,
713 const std::string &folder,
const Twine &subfolder1,
const Twine &subfolder2,
714 const Twine &subfolder3)
const {
716 llvm::sys::path::append(path, subfolder1, subfolder2, subfolder3);
721 ArgStringList &CC1Args)
const {
722 if (DriverArgs.hasArg(options::OPT_nostdinc))
725 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
731 for (
const auto &Path : DriverArgs.getAllArgValues(options::OPT__SLASH_imsvc))
734 auto AddSystemIncludesFromEnv = [&](StringRef Var) ->
bool {
735 if (
auto Val = llvm::sys::Process::GetEnv(Var)) {
737 StringRef(*Val).split(Dirs,
";", -1,
false);
747 for (
const auto &Var :
748 DriverArgs.getAllArgValues(options::OPT__SLASH_external_env)) {
749 AddSystemIncludesFromEnv(Var);
753 if (
const Arg *A = DriverArgs.getLastArg(options::OPT__SLASH_diasdkdir,
754 options::OPT__SLASH_winsysroot)) {
759 if (A->getOption().getID() == options::OPT__SLASH_winsysroot)
760 llvm::sys::path::append(DIASDKPath,
"DIA SDK");
765 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
770 if (!DriverArgs.getLastArg(options::OPT__SLASH_vctoolsdir,
771 options::OPT__SLASH_winsysroot)) {
772 bool Found = AddSystemIncludesFromEnv(
"INCLUDE");
773 Found |= AddSystemIncludesFromEnv(
"EXTERNAL_INCLUDE");
780 if (!VCToolChainPath.empty()) {
788 std::string UniversalCRTSdkPath;
789 std::string UCRTVersion;
790 if (llvm::getUniversalCRTSdkDir(
getVFS(), WinSdkDir, WinSdkVersion,
791 WinSysRoot, UniversalCRTSdkPath,
793 if (!(WinSdkDir.has_value() || WinSysRoot.has_value()) &&
794 WinSdkVersion.has_value())
795 UCRTVersion = *WinSdkVersion;
797 "Include", UCRTVersion,
"ucrt");
801 std::string WindowsSDKDir;
803 std::string windowsSDKIncludeVersion;
804 std::string windowsSDKLibVersion;
805 if (llvm::getWindowsSDKDir(
getVFS(), WinSdkDir, WinSdkVersion, WinSysRoot,
806 WindowsSDKDir, major, windowsSDKIncludeVersion,
807 windowsSDKLibVersion)) {
809 if (!(WinSdkDir.has_value() || WinSysRoot.has_value()) &&
810 WinSdkVersion.has_value())
811 windowsSDKIncludeVersion = windowsSDKLibVersion = *WinSdkVersion;
816 "Include", windowsSDKIncludeVersion,
819 "Include", windowsSDKIncludeVersion,
822 "Include", windowsSDKIncludeVersion,
825 llvm::VersionTuple Tuple;
826 if (!Tuple.tryParse(windowsSDKIncludeVersion) &&
827 Tuple.getSubminor().value_or(0) >= 17134) {
829 "Include", windowsSDKIncludeVersion,
845 const StringRef Paths[] = {
846 "C:/Program Files/Microsoft Visual Studio 10.0/VC/include",
847 "C:/Program Files/Microsoft Visual Studio 9.0/VC/include",
848 "C:/Program Files/Microsoft Visual Studio 9.0/VC/PlatformSDK/Include",
849 "C:/Program Files/Microsoft Visual Studio 8/VC/include",
850 "C:/Program Files/Microsoft Visual Studio 8/VC/PlatformSDK/Include"
857 ArgStringList &CC1Args)
const {
862 const ArgList &Args)
const {
863 bool IsWindowsMSVC =
getTriple().isWindowsMSVCEnvironment();
866 MSVT =
getTriple().getEnvironmentVersion();
867 if (MSVT.empty() && IsWindowsMSVC)
871 Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions,
877 MSVT = VersionTuple(19, 33);
888 MSVT = VersionTuple(MSVT.getMajor(), MSVT.getMinor().value_or(0),
889 MSVT.getSubminor().value_or(0));
894 if (Triple.getEnvironment() == llvm::Triple::MSVC) {
895 StringRef ObjFmt = Triple.getEnvironmentName().split(
'-').second;
897 Triple.setEnvironmentName((Twine(
"msvc") + MSVT.getAsString()).str());
899 Triple.setEnvironmentName(
900 (Twine(
"msvc") + MSVT.getAsString() + Twine(
'-') + ObjFmt).str());
902 return Triple.getTriple();
907 Res |= SanitizerKind::Address;
908 Res |= SanitizerKind::PointerCompare;
909 Res |= SanitizerKind::PointerSubtract;
910 Res |= SanitizerKind::Fuzzer;
911 Res |= SanitizerKind::FuzzerNoLink;
917 bool SupportsForcingFramePointer,
918 const char *ExpandChar,
const OptTable &Opts) {
919 assert(A->getOption().matches(options::OPT__SLASH_O));
921 StringRef OptStr = A->getValue();
922 for (
size_t I = 0, E = OptStr.size(); I != E; ++I) {
923 const char &OptChar = *(OptStr.data() + I);
934 if (&OptChar != ExpandChar) {
938 if (OptChar ==
'd') {
939 DAL.AddFlagArg(A, Opts.getOption(options::OPT_O0));
941 if (OptChar ==
'1') {
942 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O),
"s");
943 }
else if (OptChar ==
'2' || OptChar ==
'x') {
944 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
945 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O),
"2");
946 }
else if (OptChar ==
'3') {
947 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
948 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O),
"3");
950 if (SupportsForcingFramePointer &&
951 !DAL.hasArgNoClaim(options::OPT_fno_omit_frame_pointer))
952 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fomit_frame_pointer));
953 if (OptChar ==
'1' || OptChar ==
'2' || OptChar ==
'3')
954 DAL.AddFlagArg(A, Opts.getOption(options::OPT_ffunction_sections));
958 if (I + 1 != E && isdigit(OptStr[I + 1])) {
959 switch (OptStr[I + 1]) {
961 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_inline));
964 DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_hint_functions));
967 DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_functions));
977 if (I + 1 != E && OptStr[I + 1] ==
'-') {
979 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_builtin));
981 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
985 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O),
"s");
988 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O),
"2");
991 bool OmitFramePointer =
true;
992 if (I + 1 != E && OptStr[I + 1] ==
'-') {
993 OmitFramePointer =
false;
996 if (SupportsForcingFramePointer) {
997 if (OmitFramePointer)
999 Opts.getOption(options::OPT_fomit_frame_pointer));
1002 A, Opts.getOption(options::OPT_fno_omit_frame_pointer));
1017 const OptTable &Opts) {
1018 assert(A->getOption().matches(options::OPT_D));
1020 StringRef Val = A->getValue();
1021 size_t Hash = Val.find(
'#');
1022 if (Hash == StringRef::npos || Hash > Val.find(
'=')) {
1027 std::string NewVal = std::string(Val);
1029 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_D), NewVal);
1033 const OptTable &Opts) {
1034 DAL.AddFlagArg(A, Opts.getOption(options::OPT__SLASH_Zc_twoPhase_));
1035 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_operator_names));
1039 const OptTable &Opts) {
1040 DAL.AddFlagArg(A, Opts.getOption(options::OPT__SLASH_Zc_twoPhase));
1041 DAL.AddFlagArg(A, Opts.getOption(options::OPT_foperator_names));
1044 llvm::opt::DerivedArgList *
1046 StringRef BoundArch,
1048 DerivedArgList *DAL =
new DerivedArgList(Args.getBaseArgs());
1052 bool SupportsForcingFramePointer =
getArch() != llvm::Triple::x86_64;
1063 const char *ExpandChar =
nullptr;
1064 for (Arg *A : Args.filtered(options::OPT__SLASH_O)) {
1065 StringRef OptStr = A->getValue();
1066 for (
size_t I = 0, E = OptStr.size(); I != E; ++I) {
1067 char OptChar = OptStr[I];
1068 char PrevChar = I > 0 ? OptStr[I - 1] :
'0';
1069 if (PrevChar ==
'b') {
1073 if (OptChar ==
'1' || OptChar ==
'2' || OptChar ==
'x' ||
1074 OptChar ==
'd' || OptChar ==
'3')
1075 ExpandChar = OptStr.data() + I;
1079 for (Arg *A : Args) {
1080 if (A->getOption().matches(options::OPT__SLASH_O)) {
1083 TranslateOptArg(A, *DAL, SupportsForcingFramePointer, ExpandChar, Opts);
1084 }
else if (A->getOption().matches(options::OPT_D)) {
1087 }
else if (A->getOption().matches(options::OPT__SLASH_permissive)) {
1090 }
else if (A->getOption().matches(options::OPT__SLASH_permissive_)) {
1103 const ArgList &DriverArgs, ArgStringList &CC1Args,
1107 if (DriverArgs.hasFlag(options::OPT_fno_rtti, options::OPT_frtti,
1109 CC1Args.push_back(
"-D_HAS_STATIC_RTTI=0");
1111 if (Arg *A = DriverArgs.getLastArgNoClaim(options::OPT_marm64x))
1112 A->ignoreTargetSpecific();
static void TranslatePermissiveMinus(Arg *A, llvm::opt::DerivedArgList &DAL, const OptTable &Opts)
static VersionTuple getMSVCVersionFromExe(const std::string &BinDir)
static bool canExecute(llvm::vfs::FileSystem &VFS, StringRef Path)
static std::string FindVisualStudioExecutable(const ToolChain &TC, const char *Exe)
static void TranslateDArg(Arg *A, llvm::opt::DerivedArgList &DAL, const OptTable &Opts)
static void TranslateOptArg(Arg *A, llvm::opt::DerivedArgList &DAL, bool SupportsForcingFramePointer, const char *ExpandChar, const OptTable &Opts)
static void TranslatePermissive(Arg *A, llvm::opt::DerivedArgList &DAL, const OptTable &Opts)
Defines version macros and version-related utility functions for Clang.
The base class of the type hierarchy.
types::ID getType() const
Compilation - A set of tasks to perform for a single driver invocation.
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
DiagnosticBuilder Diag(unsigned DiagID) const
const llvm::opt::OptTable & getOpts() const
@ OMPRT_IOMP5
The legacy name for the LLVM OpenMP runtime from when it was the Intel OpenMP runtime.
@ OMPRT_OMP
The LLVM OpenMP runtime.
@ OMPRT_Unknown
An unknown OpenMP runtime.
@ OMPRT_GOMP
The GNU OpenMP runtime.
The JSON file list parser is used to communicate input to InstallAPI.
static constexpr ResponseFileSupport AtFileUTF16()