69 const char *LinkingOutput)
const {
70 ArgStringList CmdArgs;
77 Args.MakeArgString(std::string(
"-out:") + Output.
getFilename()));
79 if (Args.hasArg(options::OPT_marm64x))
80 CmdArgs.push_back(
"-machine:arm64x");
81 else if (TC.getTriple().isWindowsArm64EC())
82 CmdArgs.push_back(
"-machine:arm64ec");
84 if (
const Arg *A = Args.getLastArg(options::OPT_fveclib)) {
85 StringRef
V = A->getValue();
87 CmdArgs.push_back(Args.MakeArgString(
"--dependent-lib=amath"));
93 if (Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl,
false) &&
94 !Args.hasArg(options::OPT_nolibsycl) &&
95 !Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
99 bool HasStaticCRT =
false;
101 if (
const Arg *A = Args.getLastArg(options::OPT_fms_runtime_lib_EQ)) {
102 StringRef RuntimeLib = A->getValue();
103 if (RuntimeLib ==
"static" || RuntimeLib ==
"static_dbg")
107 if (
const Arg *A = Args.getLastArg(options::OPT__SLASH_M_Group)) {
108 if (A->getOption().matches(options::OPT__SLASH_MT) ||
109 A->getOption().matches(options::OPT__SLASH_MTd))
114 TC.getDriver().Diag(diag::err_drv_sycl_requires_dynamic_crt);
118 llvm::sys::path::append(LibPath,
"..",
"lib");
119 CmdArgs.push_back(Args.MakeArgString(Twine(
"-libpath:") + LibPath));
123 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles) &&
124 !
C.getDriver().IsCLMode() && !
C.getDriver().IsFlangMode()) {
125 CmdArgs.push_back(
"-defaultlib:libcmt");
126 CmdArgs.push_back(
"-defaultlib:oldnames");
130 if (Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl,
false) &&
131 !Args.hasArg(options::OPT_nolibsycl)) {
132 bool IsDebugBuild =
false;
133 if (
const Arg *A = Args.getLastArg(options::OPT_fms_runtime_lib_EQ)) {
134 StringRef RuntimeVal = A->getValue();
135 if (RuntimeVal ==
"dll_dbg")
138 CmdArgs.push_back(IsDebugBuild ?
"-defaultlib:LLVMSYCLd"
139 :
"-defaultlib:LLVMSYCL");
148 if (
const Arg *A = Args.getLastArg(options::OPT__SLASH_diasdkdir,
149 options::OPT__SLASH_winsysroot)) {
154 if (A->getOption().getID() == options::OPT__SLASH_winsysroot)
155 llvm::sys::path::append(DIAPath,
"DIA SDK");
158 llvm::sys::path::append(DIAPath,
"lib",
159 llvm::archToLegacyVCArch(TC.getArch()));
160 CmdArgs.push_back(Args.MakeArgString(Twine(
"-libpath:") + DIAPath));
162 if (!llvm::sys::Process::GetEnv(
"LIB") ||
163 Args.hasArg(options::OPT__SLASH_vctoolsdir,
164 options::OPT__SLASH_vctoolsversion,
165 options::OPT__SLASH_winsysroot)) {
166 CmdArgs.push_back(Args.MakeArgString(
168 TC.getSubDirectoryPath(llvm::SubDirectoryType::Lib)));
169 CmdArgs.push_back(Args.MakeArgString(
171 TC.getSubDirectoryPath(llvm::SubDirectoryType::Lib,
"atlmfc")));
173 if (!llvm::sys::Process::GetEnv(
"LIB") ||
174 Args.hasArg(options::OPT__SLASH_winsdkdir,
175 options::OPT__SLASH_winsdkversion,
176 options::OPT__SLASH_winsysroot)) {
177 if (TC.useUniversalCRT()) {
178 std::string UniversalCRTLibPath;
179 if (TC.getUniversalCRTLibraryPath(Args, UniversalCRTLibPath))
181 Args.MakeArgString(Twine(
"-libpath:") + UniversalCRTLibPath));
183 std::string WindowsSdkLibPath;
184 if (TC.getWindowsSDKLibraryPath(Args, WindowsSdkLibPath))
186 Args.MakeArgString(std::string(
"-libpath:") + WindowsSdkLibPath));
189 if (!
C.getDriver().IsCLMode() && Args.hasArg(options::OPT_L))
190 for (
const auto &LibPath : Args.getAllArgValues(options::OPT_L))
191 CmdArgs.push_back(Args.MakeArgString(
"-libpath:" + LibPath));
193 if (
C.getDriver().IsFlangMode() &&
194 !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
195 TC.addFortranRuntimeLibraryPath(Args, CmdArgs);
196 TC.addFortranRuntimeLibs(Args, CmdArgs);
201 CmdArgs.push_back(
"/subsystem:console");
206 for (
const auto &LibPath : TC.getLibraryPaths()) {
207 if (TC.getVFS().exists(LibPath))
208 CmdArgs.push_back(Args.MakeArgString(
"-libpath:" + LibPath));
210 for (
const auto &LibPath : TC.getFilePaths()) {
211 if (LibPath.length() > 0)
212 CmdArgs.push_back(Args.MakeArgString(
"-libpath:" + LibPath));
214 auto CRTPath = TC.getCompilerRTPath();
215 if (TC.getVFS().exists(CRTPath))
216 CmdArgs.push_back(Args.MakeArgString(
"-libpath:" + CRTPath));
221 if (Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl,
false))
222 CmdArgs.push_back(
"/IGNORE:4078");
224 CmdArgs.push_back(
"-nologo");
226 if (Args.hasArg(options::OPT_g_Group, options::OPT__SLASH_Z7))
227 CmdArgs.push_back(
"-debug");
231 if (Args.hasArg(options::OPT_fms_hotpatch, options::OPT__SLASH_hotpatch))
232 CmdArgs.push_back(
"-functionpadmin");
236 bool DefaultIncrementalLinkerCompatible =
237 C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment();
238 if (!Args.hasFlag(options::OPT_mincremental_linker_compatible,
239 options::OPT_mno_incremental_linker_compatible,
240 DefaultIncrementalLinkerCompatible))
241 CmdArgs.push_back(
"-Brepro");
243 bool DLL = Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd,
244 options::OPT_shared);
246 CmdArgs.push_back(Args.MakeArgString(
"-dll"));
249 llvm::sys::path::replace_extension(ImplibName,
"lib");
250 CmdArgs.push_back(Args.MakeArgString(std::string(
"-implib:") + ImplibName));
253 if (TC.getSanitizerArgs(Args).needsFuzzer()) {
254 if (!Args.hasArg(options::OPT_shared))
256 Args.MakeArgString(std::string(
"-wholearchive:") +
257 TC.getCompilerRTArgString(Args,
"fuzzer")));
258 CmdArgs.push_back(Args.MakeArgString(
"-debug"));
261 CmdArgs.push_back(Args.MakeArgString(
"-incremental:no"));
264 if (TC.getSanitizerArgs(Args).needsAsanRt()) {
265 CmdArgs.push_back(Args.MakeArgString(
"-debug"));
266 CmdArgs.push_back(Args.MakeArgString(
"-incremental:no"));
267 CmdArgs.push_back(TC.getCompilerRTArgString(Args,
"asan_dynamic"));
268 auto defines = Args.getAllArgValues(options::OPT_D);
269 if (Args.hasArg(options::OPT__SLASH_MD, options::OPT__SLASH_MDd) ||
270 llvm::is_contained(defines,
"_DLL")) {
273 CmdArgs.push_back(Args.MakeArgString(
274 TC.getArch() == llvm::Triple::x86
275 ?
"-include:___asan_seh_interceptor"
276 :
"-include:__asan_seh_interceptor"));
279 CmdArgs.push_back(Args.MakeArgString(
280 std::string(
"-wholearchive:") +
281 TC.getCompilerRT(Args,
"asan_dynamic_runtime_thunk")));
285 CmdArgs.push_back(Args.MakeArgString(
286 std::string(
"-wholearchive:") +
287 TC.getCompilerRT(Args,
"asan_static_runtime_thunk")));
291 if (TC.isUsingLTO(Args)) {
293 CmdArgs.push_back(Args.MakeArgString(std::string(
"-lto-sample-profile:") +
296 Args.AddAllArgValues(CmdArgs, options::OPT__SLASH_link);
299 for (
const Arg *A : Args.filtered(options::OPT__SLASH_guard)) {
300 StringRef GuardArgs = A->getValue();
301 if (GuardArgs.equals_insensitive(
"cf") ||
302 GuardArgs.equals_insensitive(
"cf,nochecks")) {
304 CmdArgs.push_back(
"-guard:cf");
305 }
else if (GuardArgs.equals_insensitive(
"cf-")) {
306 CmdArgs.push_back(
"-guard:cf-");
307 }
else if (GuardArgs.equals_insensitive(
"ehcont")) {
308 CmdArgs.push_back(
"-guard:ehcont");
309 }
else if (GuardArgs.equals_insensitive(
"ehcont-")) {
310 CmdArgs.push_back(
"-guard:ehcont-");
314 if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
315 options::OPT_fno_openmp,
false)) {
316 CmdArgs.push_back(
"-nodefaultlib:vcomp.lib");
317 CmdArgs.push_back(
"-nodefaultlib:vcompd.lib");
318 CmdArgs.push_back(Args.MakeArgString(std::string(
"-libpath:") +
319 TC.getDriver().Dir +
"/../lib"));
320 switch (TC.getDriver().getOpenMPRuntime(Args)) {
322 CmdArgs.push_back(
"-defaultlib:libomp.lib");
325 CmdArgs.push_back(
"-defaultlib:libiomp5md.lib");
337 if (!Args.hasArg(options::OPT_nostdlib)) {
341 const Arg *A = Args.getLastArg(options::OPT_fuse_ld_EQ);
342 StringRef
Linker = A ? A->getValue() : TC.getDriver().getPreferredLinker();
350 if (Args.hasArg(options::OPT_gdwarf, options::OPT_gdwarf_2,
351 options::OPT_gdwarf_3, options::OPT_gdwarf_4,
352 options::OPT_gdwarf_5, options::OPT_gdwarf_6,
353 options::OPT_marm64x))
360 if (
Linker.equals_insensitive(
"lld"))
363 if (
Linker ==
"lld-link") {
364 for (Arg *A : Args.filtered(options::OPT_vfsoverlay))
366 Args.MakeArgString(std::string(
"/vfsoverlay:") + A->getValue()));
368 if (TC.isUsingLTO(Args) &&
369 Args.hasFlag(options::OPT_gsplit_dwarf, options::OPT_gno_split_dwarf,
371 CmdArgs.push_back(Args.MakeArgString(Twine(
"/dwodir:") +
376 for (
const auto &Input : Inputs) {
377 if (Input.isFilename()) {
378 CmdArgs.push_back(Input.getFilename());
382 const Arg &A = Input.getInputArg();
385 if (A.getOption().matches(options::OPT_l)) {
386 StringRef Lib = A.getValue();
387 const char *LinkLibArg;
388 if (Lib.ends_with(
".lib"))
389 LinkLibArg = Args.MakeArgString(Lib);
391 LinkLibArg = Args.MakeArgString(Lib +
".lib");
392 CmdArgs.push_back(LinkLibArg);
398 A.renderAsInput(Args, CmdArgs);
401 TC.addOffloadRTLibs(
C.getActiveOffloadKinds(), Args, CmdArgs);
403 TC.addProfileRTLibs(Args, CmdArgs);
405 std::vector<const char *> Environment;
410 if (
Linker.equals_insensitive(
"link")) {
416 if (!TC.FoundMSVCInstall() && !
canExecute(TC.getVFS(), linkPath)) {
418 ClPath = TC.GetProgramPath(
"cl.exe");
420 linkPath = llvm::sys::path::parent_path(ClPath);
421 llvm::sys::path::append(linkPath,
"link.exe");
423 C.getDriver().Diag(clang::diag::warn_drv_msvc_not_found);
425 C.getDriver().Diag(clang::diag::warn_drv_msvc_not_found);
431 if (TC.getSanitizerArgs(Args).needsAsanRt())
432 CmdArgs.push_back(
"/INFERASANLIBS:NO");
441 if (TC.getIsVS2017OrNewer() &&
442 llvm::Triple(llvm::sys::getProcessTriple()).getArch() != TC.getArch()) {
443 auto HostArch = llvm::Triple(llvm::sys::getProcessTriple()).getArch();
446 std::unique_ptr<wchar_t[], decltype(&FreeEnvironmentStringsW)>(
447 GetEnvironmentStringsW(), FreeEnvironmentStringsW);
449 goto SkipSettingEnvironment;
452 size_t EnvBlockLen = 0;
453 while (EnvBlockWide[EnvBlockLen] != L
'\0') {
455 EnvBlockLen += std::wcslen(&EnvBlockWide[EnvBlockLen]) +
460 std::string EnvBlock;
461 if (!llvm::convertUTF16ToUTF8String(
463 EnvBlockLen *
sizeof(EnvBlockWide[0])),
465 goto SkipSettingEnvironment;
467 Environment.reserve(EnvCount);
472 for (
const char *Cursor = EnvBlock.data(); *Cursor !=
'\0';) {
473 llvm::StringRef EnvVar(Cursor);
474 if (EnvVar.starts_with_insensitive(
"path=")) {
475 constexpr size_t PrefixLen = 5;
476 Environment.push_back(Args.MakeArgString(
477 EnvVar.substr(0, PrefixLen) +
478 TC.getSubDirectoryPath(llvm::SubDirectoryType::Bin) +
479 llvm::Twine(llvm::sys::EnvPathSeparator) +
480 TC.getSubDirectoryPath(llvm::SubDirectoryType::Bin, HostArch) +
481 (EnvVar.size() > PrefixLen
482 ? llvm::Twine(llvm::sys::EnvPathSeparator) +
483 EnvVar.substr(PrefixLen)
486 Environment.push_back(Args.MakeArgString(EnvVar));
488 Cursor += EnvVar.size() + 1 ;
491 SkipSettingEnvironment:;
494 linkPath = TC.GetProgramPath(
Linker.str().c_str());
497 auto LinkCmd = std::make_unique<Command>(
499 Args.MakeArgString(linkPath), CmdArgs, Inputs, Output);
500 if (!Environment.empty())
501 LinkCmd->setEnvironment(Environment);
502 C.addCommand(std::move(LinkCmd));
813 ArgStringList &CC1Args)
const {
814 if (DriverArgs.hasArg(options::OPT_nostdinc))
817 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
823 for (
const auto &Path : DriverArgs.getAllArgValues(options::OPT__SLASH_imsvc))
826 auto AddSystemIncludesFromEnv = [&](StringRef Var) ->
bool {
827 if (
auto Val = llvm::sys::Process::GetEnv(Var)) {
829 StringRef(*Val).split(Dirs,
";", -1,
false);
839 for (
const auto &Var :
840 DriverArgs.getAllArgValues(options::OPT__SLASH_external_env)) {
841 AddSystemIncludesFromEnv(Var);
845 if (
const Arg *A = DriverArgs.getLastArg(options::OPT__SLASH_diasdkdir,
846 options::OPT__SLASH_winsysroot)) {
851 if (A->getOption().getID() == options::OPT__SLASH_winsysroot)
852 llvm::sys::path::append(DIASDKPath,
"DIA SDK");
857 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
866 if (!DriverArgs.hasArg(
867 options::OPT__SLASH_vctoolsdir, options::OPT__SLASH_vctoolsversion,
868 options::OPT__SLASH_winsysroot, options::OPT__SLASH_winsdkdir,
869 options::OPT__SLASH_winsdkversion)) {
870 bool Found = AddSystemIncludesFromEnv(
"INCLUDE");
871 Found |= AddSystemIncludesFromEnv(
"EXTERNAL_INCLUDE");
878 if (!VCToolChainPath.empty()) {
886 std::string UniversalCRTSdkPath;
887 std::string UCRTVersion;
888 if (llvm::getUniversalCRTSdkDir(
getVFS(), WinSdkDir, WinSdkVersion,
889 WinSysRoot, UniversalCRTSdkPath,
891 if (!(WinSdkDir.has_value() || WinSysRoot.has_value()) &&
892 WinSdkVersion.has_value())
893 UCRTVersion = *WinSdkVersion;
895 "Include", UCRTVersion,
"ucrt");
899 std::string WindowsSDKDir;
901 std::string windowsSDKIncludeVersion;
902 std::string windowsSDKLibVersion;
903 if (llvm::getWindowsSDKDir(
getVFS(), WinSdkDir, WinSdkVersion, WinSysRoot,
904 WindowsSDKDir, major, windowsSDKIncludeVersion,
905 windowsSDKLibVersion)) {
907 if (!(WinSdkDir.has_value() || WinSysRoot.has_value()) &&
908 WinSdkVersion.has_value())
909 windowsSDKIncludeVersion = windowsSDKLibVersion = *WinSdkVersion;
914 "Include", windowsSDKIncludeVersion,
917 "Include", windowsSDKIncludeVersion,
920 "Include", windowsSDKIncludeVersion,
923 llvm::VersionTuple Tuple;
924 if (!Tuple.tryParse(windowsSDKIncludeVersion) &&
925 Tuple.getSubminor().value_or(0) >= 17134) {
927 "Include", windowsSDKIncludeVersion,
943 const StringRef Paths[] = {
944 "C:/Program Files/Microsoft Visual Studio 10.0/VC/include",
945 "C:/Program Files/Microsoft Visual Studio 9.0/VC/include",
946 "C:/Program Files/Microsoft Visual Studio 9.0/VC/PlatformSDK/Include",
947 "C:/Program Files/Microsoft Visual Studio 8/VC/include",
948 "C:/Program Files/Microsoft Visual Studio 8/VC/PlatformSDK/Include"
1027 bool SupportsForcingFramePointer,
1028 const char *ExpandChar,
const OptTable &Opts) {
1029 assert(A->getOption().matches(options::OPT__SLASH_O));
1031 StringRef OptStr = A->getValue();
1032 for (
size_t I = 0, E = OptStr.size(); I != E; ++I) {
1033 const char &OptChar = *(OptStr.data() + I);
1043 if (&OptChar != ExpandChar) {
1047 if (OptChar ==
'd') {
1048 DAL.AddFlagArg(A, Opts.getOption(options::OPT_O0));
1050 if (OptChar ==
'1') {
1051 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O),
"s");
1052 }
else if (OptChar ==
'2' || OptChar ==
'x') {
1053 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
1054 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O),
"3");
1056 if (SupportsForcingFramePointer &&
1057 !DAL.hasArgNoClaim(options::OPT_fno_omit_frame_pointer))
1058 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fomit_frame_pointer));
1059 if (OptChar ==
'1' || OptChar ==
'2')
1060 DAL.AddFlagArg(A, Opts.getOption(options::OPT_ffunction_sections));
1064 if (I + 1 != E && isdigit(OptStr[I + 1])) {
1065 switch (OptStr[I + 1]) {
1067 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_inline));
1070 DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_hint_functions));
1074 DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_functions));
1084 if (I + 1 != E && OptStr[I + 1] ==
'-') {
1086 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_builtin));
1088 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
1092 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O),
"s");
1095 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O),
"3");
1098 bool OmitFramePointer =
true;
1099 if (I + 1 != E && OptStr[I + 1] ==
'-') {
1100 OmitFramePointer =
false;
1103 if (SupportsForcingFramePointer) {
1104 if (OmitFramePointer)
1106 Opts.getOption(options::OPT_fomit_frame_pointer));
1109 A, Opts.getOption(options::OPT_fno_omit_frame_pointer));