67 const char *LinkingOutput)
const {
68 ArgStringList CmdArgs;
75 Args.MakeArgString(std::string(
"-out:") + Output.
getFilename()));
77 if (Args.hasArg(options::OPT_marm64x))
78 CmdArgs.push_back(
"-machine:arm64x");
79 else if (TC.getTriple().isWindowsArm64EC())
80 CmdArgs.push_back(
"-machine:arm64ec");
82 if (
const Arg *A = Args.getLastArg(options::OPT_fveclib)) {
83 StringRef
V = A->getValue();
85 CmdArgs.push_back(Args.MakeArgString(
"--dependent-lib=amath"));
91 if (Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl,
false) &&
92 !Args.hasArg(options::OPT_nolibsycl) &&
93 !Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
97 bool HasStaticCRT =
false;
99 if (
const Arg *A = Args.getLastArg(options::OPT_fms_runtime_lib_EQ)) {
100 StringRef RuntimeLib = A->getValue();
101 if (RuntimeLib ==
"static" || RuntimeLib ==
"static_dbg")
105 if (
const Arg *A = Args.getLastArg(options::OPT__SLASH_M_Group)) {
106 if (A->getOption().matches(options::OPT__SLASH_MT) ||
107 A->getOption().matches(options::OPT__SLASH_MTd))
112 TC.getDriver().Diag(diag::err_drv_sycl_requires_dynamic_crt);
116 llvm::sys::path::append(LibPath,
"..",
"lib");
117 CmdArgs.push_back(Args.MakeArgString(Twine(
"-libpath:") + LibPath));
121 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles) &&
122 !
C.getDriver().IsCLMode() && !
C.getDriver().IsFlangMode()) {
123 CmdArgs.push_back(
"-defaultlib:libcmt");
124 CmdArgs.push_back(
"-defaultlib:oldnames");
128 if (Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl,
false) &&
129 !Args.hasArg(options::OPT_nolibsycl)) {
130 bool IsDebugBuild =
false;
131 if (
const Arg *A = Args.getLastArg(options::OPT_fms_runtime_lib_EQ)) {
132 StringRef RuntimeVal = A->getValue();
133 if (RuntimeVal ==
"dll_dbg")
136 CmdArgs.push_back(IsDebugBuild ?
"-defaultlib:LLVMSYCLd"
137 :
"-defaultlib:LLVMSYCL");
146 if (
const Arg *A = Args.getLastArg(options::OPT__SLASH_diasdkdir,
147 options::OPT__SLASH_winsysroot)) {
152 if (A->getOption().getID() == options::OPT__SLASH_winsysroot)
153 llvm::sys::path::append(DIAPath,
"DIA SDK");
156 llvm::sys::path::append(DIAPath,
"lib",
157 llvm::archToLegacyVCArch(TC.getArch()));
158 CmdArgs.push_back(Args.MakeArgString(Twine(
"-libpath:") + DIAPath));
160 if (!llvm::sys::Process::GetEnv(
"LIB") ||
161 Args.hasArg(options::OPT__SLASH_vctoolsdir,
162 options::OPT__SLASH_vctoolsversion,
163 options::OPT__SLASH_winsysroot)) {
164 CmdArgs.push_back(Args.MakeArgString(
166 TC.getSubDirectoryPath(llvm::SubDirectoryType::Lib)));
167 CmdArgs.push_back(Args.MakeArgString(
169 TC.getSubDirectoryPath(llvm::SubDirectoryType::Lib,
"atlmfc")));
171 if (!llvm::sys::Process::GetEnv(
"LIB") ||
172 Args.hasArg(options::OPT__SLASH_winsdkdir,
173 options::OPT__SLASH_winsdkversion,
174 options::OPT__SLASH_winsysroot)) {
175 if (TC.useUniversalCRT()) {
176 std::string UniversalCRTLibPath;
177 if (TC.getUniversalCRTLibraryPath(Args, UniversalCRTLibPath))
179 Args.MakeArgString(Twine(
"-libpath:") + UniversalCRTLibPath));
181 std::string WindowsSdkLibPath;
182 if (TC.getWindowsSDKLibraryPath(Args, WindowsSdkLibPath))
184 Args.MakeArgString(std::string(
"-libpath:") + WindowsSdkLibPath));
187 if (!
C.getDriver().IsCLMode() && Args.hasArg(options::OPT_L))
188 for (
const auto &LibPath : Args.getAllArgValues(options::OPT_L))
189 CmdArgs.push_back(Args.MakeArgString(
"-libpath:" + LibPath));
191 if (
C.getDriver().IsFlangMode() &&
192 !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
193 TC.addFortranRuntimeLibraryPath(Args, CmdArgs);
194 TC.addFortranRuntimeLibs(Args, CmdArgs);
199 CmdArgs.push_back(
"/subsystem:console");
204 for (
const auto &LibPath : TC.getLibraryPaths()) {
205 if (TC.getVFS().exists(LibPath))
206 CmdArgs.push_back(Args.MakeArgString(
"-libpath:" + LibPath));
208 for (
const auto &LibPath : TC.getFilePaths()) {
209 if (LibPath.length() > 0)
210 CmdArgs.push_back(Args.MakeArgString(
"-libpath:" + LibPath));
212 auto CRTPath = TC.getCompilerRTPath();
213 if (TC.getVFS().exists(CRTPath))
214 CmdArgs.push_back(Args.MakeArgString(
"-libpath:" + CRTPath));
219 if (Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl,
false))
220 CmdArgs.push_back(
"/IGNORE:4078");
222 CmdArgs.push_back(
"-nologo");
224 if (Args.hasArg(options::OPT_g_Group, options::OPT__SLASH_Z7))
225 CmdArgs.push_back(
"-debug");
229 if (Args.hasArg(options::OPT_fms_hotpatch, options::OPT__SLASH_hotpatch))
230 CmdArgs.push_back(
"-functionpadmin");
234 bool DefaultIncrementalLinkerCompatible =
235 C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment();
236 if (!Args.hasFlag(options::OPT_mincremental_linker_compatible,
237 options::OPT_mno_incremental_linker_compatible,
238 DefaultIncrementalLinkerCompatible))
239 CmdArgs.push_back(
"-Brepro");
241 bool DLL = Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd,
242 options::OPT_shared);
244 CmdArgs.push_back(Args.MakeArgString(
"-dll"));
247 llvm::sys::path::replace_extension(ImplibName,
"lib");
248 CmdArgs.push_back(Args.MakeArgString(std::string(
"-implib:") + ImplibName));
251 if (TC.getSanitizerArgs(Args).needsFuzzer()) {
252 if (!Args.hasArg(options::OPT_shared))
254 Args.MakeArgString(std::string(
"-wholearchive:") +
255 TC.getCompilerRTArgString(Args,
"fuzzer")));
256 CmdArgs.push_back(Args.MakeArgString(
"-debug"));
259 CmdArgs.push_back(Args.MakeArgString(
"-incremental:no"));
262 if (TC.getSanitizerArgs(Args).needsAsanRt()) {
263 CmdArgs.push_back(Args.MakeArgString(
"-debug"));
264 CmdArgs.push_back(Args.MakeArgString(
"-incremental:no"));
265 CmdArgs.push_back(TC.getCompilerRTArgString(Args,
"asan_dynamic"));
266 auto defines = Args.getAllArgValues(options::OPT_D);
267 if (Args.hasArg(options::OPT__SLASH_MD, options::OPT__SLASH_MDd) ||
268 llvm::is_contained(defines,
"_DLL")) {
271 CmdArgs.push_back(Args.MakeArgString(
272 TC.getArch() == llvm::Triple::x86
273 ?
"-include:___asan_seh_interceptor"
274 :
"-include:__asan_seh_interceptor"));
277 CmdArgs.push_back(Args.MakeArgString(
278 std::string(
"-wholearchive:") +
279 TC.getCompilerRT(Args,
"asan_dynamic_runtime_thunk")));
283 CmdArgs.push_back(Args.MakeArgString(
284 std::string(
"-wholearchive:") +
285 TC.getCompilerRT(Args,
"asan_static_runtime_thunk")));
289 if (TC.isUsingLTO(Args)) {
291 CmdArgs.push_back(Args.MakeArgString(std::string(
"-lto-sample-profile:") +
294 Args.AddAllArgValues(CmdArgs, options::OPT__SLASH_link);
297 for (
const Arg *A : Args.filtered(options::OPT__SLASH_guard)) {
298 StringRef GuardArgs = A->getValue();
299 if (GuardArgs.equals_insensitive(
"cf") ||
300 GuardArgs.equals_insensitive(
"cf,nochecks")) {
302 CmdArgs.push_back(
"-guard:cf");
303 }
else if (GuardArgs.equals_insensitive(
"cf-")) {
304 CmdArgs.push_back(
"-guard:cf-");
305 }
else if (GuardArgs.equals_insensitive(
"ehcont")) {
306 CmdArgs.push_back(
"-guard:ehcont");
307 }
else if (GuardArgs.equals_insensitive(
"ehcont-")) {
308 CmdArgs.push_back(
"-guard:ehcont-");
312 if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
313 options::OPT_fno_openmp,
false)) {
314 CmdArgs.push_back(
"-nodefaultlib:vcomp.lib");
315 CmdArgs.push_back(
"-nodefaultlib:vcompd.lib");
316 CmdArgs.push_back(Args.MakeArgString(std::string(
"-libpath:") +
317 TC.getDriver().Dir +
"/../lib"));
318 switch (TC.getDriver().getOpenMPRuntime(Args)) {
320 CmdArgs.push_back(
"-defaultlib:libomp.lib");
323 CmdArgs.push_back(
"-defaultlib:libiomp5md.lib");
335 if (!Args.hasArg(options::OPT_nostdlib)) {
339 const Arg *A = Args.getLastArg(options::OPT_fuse_ld_EQ);
340 StringRef
Linker = A ? A->getValue() : TC.getDriver().getPreferredLinker();
348 if (Args.hasArg(options::OPT_gdwarf, options::OPT_gdwarf_2,
349 options::OPT_gdwarf_3, options::OPT_gdwarf_4,
350 options::OPT_gdwarf_5, options::OPT_gdwarf_6,
351 options::OPT_marm64x))
358 if (
Linker.equals_insensitive(
"lld"))
361 if (
Linker ==
"lld-link") {
362 for (Arg *A : Args.filtered(options::OPT_vfsoverlay))
364 Args.MakeArgString(std::string(
"/vfsoverlay:") + A->getValue()));
366 if (TC.isUsingLTO(Args) &&
367 Args.hasFlag(options::OPT_gsplit_dwarf, options::OPT_gno_split_dwarf,
369 CmdArgs.push_back(Args.MakeArgString(Twine(
"/dwodir:") +
374 for (
const auto &Input : Inputs) {
375 if (Input.isFilename()) {
376 CmdArgs.push_back(Input.getFilename());
380 const Arg &A = Input.getInputArg();
383 if (A.getOption().matches(options::OPT_l)) {
384 StringRef Lib = A.getValue();
385 const char *LinkLibArg;
386 if (Lib.ends_with(
".lib"))
387 LinkLibArg = Args.MakeArgString(Lib);
389 LinkLibArg = Args.MakeArgString(Lib +
".lib");
390 CmdArgs.push_back(LinkLibArg);
396 A.renderAsInput(Args, CmdArgs);
399 TC.addOffloadRTLibs(
C.getActiveOffloadKinds(), Args, CmdArgs);
401 TC.addProfileRTLibs(Args, CmdArgs);
403 std::vector<const char *> Environment;
408 if (
Linker.equals_insensitive(
"link")) {
414 if (!TC.FoundMSVCInstall() && !
canExecute(TC.getVFS(), linkPath)) {
416 ClPath = TC.GetProgramPath(
"cl.exe");
418 linkPath = llvm::sys::path::parent_path(ClPath);
419 llvm::sys::path::append(linkPath,
"link.exe");
421 C.getDriver().Diag(clang::diag::warn_drv_msvc_not_found);
423 C.getDriver().Diag(clang::diag::warn_drv_msvc_not_found);
429 if (TC.getSanitizerArgs(Args).needsAsanRt())
430 CmdArgs.push_back(
"/INFERASANLIBS:NO");
439 if (TC.getIsVS2017OrNewer() &&
440 llvm::Triple(llvm::sys::getProcessTriple()).getArch() != TC.getArch()) {
441 auto HostArch = llvm::Triple(llvm::sys::getProcessTriple()).getArch();
444 std::unique_ptr<wchar_t[], decltype(&FreeEnvironmentStringsW)>(
445 GetEnvironmentStringsW(), FreeEnvironmentStringsW);
447 goto SkipSettingEnvironment;
450 size_t EnvBlockLen = 0;
451 while (EnvBlockWide[EnvBlockLen] != L
'\0') {
453 EnvBlockLen += std::wcslen(&EnvBlockWide[EnvBlockLen]) +
458 std::string EnvBlock;
459 if (!llvm::convertUTF16ToUTF8String(
461 EnvBlockLen *
sizeof(EnvBlockWide[0])),
463 goto SkipSettingEnvironment;
465 Environment.reserve(EnvCount);
470 for (
const char *Cursor = EnvBlock.data(); *Cursor !=
'\0';) {
471 llvm::StringRef EnvVar(Cursor);
472 if (EnvVar.starts_with_insensitive(
"path=")) {
473 constexpr size_t PrefixLen = 5;
474 Environment.push_back(Args.MakeArgString(
475 EnvVar.substr(0, PrefixLen) +
476 TC.getSubDirectoryPath(llvm::SubDirectoryType::Bin) +
477 llvm::Twine(llvm::sys::EnvPathSeparator) +
478 TC.getSubDirectoryPath(llvm::SubDirectoryType::Bin, HostArch) +
479 (EnvVar.size() > PrefixLen
480 ? llvm::Twine(llvm::sys::EnvPathSeparator) +
481 EnvVar.substr(PrefixLen)
484 Environment.push_back(Args.MakeArgString(EnvVar));
486 Cursor += EnvVar.size() + 1 ;
489 SkipSettingEnvironment:;
492 linkPath = TC.GetProgramPath(
Linker.str().c_str());
495 auto LinkCmd = std::make_unique<Command>(
497 Args.MakeArgString(linkPath), CmdArgs, Inputs, Output);
498 if (!Environment.empty())
499 LinkCmd->setEnvironment(Environment);
500 C.addCommand(std::move(LinkCmd));
811 ArgStringList &CC1Args)
const {
812 if (DriverArgs.hasArg(options::OPT_nostdinc))
815 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
821 for (
const auto &Path : DriverArgs.getAllArgValues(options::OPT__SLASH_imsvc))
824 auto AddSystemIncludesFromEnv = [&](StringRef Var) ->
bool {
825 if (
auto Val = llvm::sys::Process::GetEnv(Var)) {
827 StringRef(*Val).split(Dirs,
";", -1,
false);
837 for (
const auto &Var :
838 DriverArgs.getAllArgValues(options::OPT__SLASH_external_env)) {
839 AddSystemIncludesFromEnv(Var);
843 if (
const Arg *A = DriverArgs.getLastArg(options::OPT__SLASH_diasdkdir,
844 options::OPT__SLASH_winsysroot)) {
849 if (A->getOption().getID() == options::OPT__SLASH_winsysroot)
850 llvm::sys::path::append(DIASDKPath,
"DIA SDK");
855 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
864 if (!DriverArgs.hasArg(
865 options::OPT__SLASH_vctoolsdir, options::OPT__SLASH_vctoolsversion,
866 options::OPT__SLASH_winsysroot, options::OPT__SLASH_winsdkdir,
867 options::OPT__SLASH_winsdkversion)) {
868 bool Found = AddSystemIncludesFromEnv(
"INCLUDE");
869 Found |= AddSystemIncludesFromEnv(
"EXTERNAL_INCLUDE");
876 if (!VCToolChainPath.empty()) {
884 std::string UniversalCRTSdkPath;
885 std::string UCRTVersion;
886 if (llvm::getUniversalCRTSdkDir(
getVFS(), WinSdkDir, WinSdkVersion,
887 WinSysRoot, UniversalCRTSdkPath,
889 if (!(WinSdkDir.has_value() || WinSysRoot.has_value()) &&
890 WinSdkVersion.has_value())
891 UCRTVersion = *WinSdkVersion;
893 "Include", UCRTVersion,
"ucrt");
897 std::string WindowsSDKDir;
899 std::string windowsSDKIncludeVersion;
900 std::string windowsSDKLibVersion;
901 if (llvm::getWindowsSDKDir(
getVFS(), WinSdkDir, WinSdkVersion, WinSysRoot,
902 WindowsSDKDir, major, windowsSDKIncludeVersion,
903 windowsSDKLibVersion)) {
905 if (!(WinSdkDir.has_value() || WinSysRoot.has_value()) &&
906 WinSdkVersion.has_value())
907 windowsSDKIncludeVersion = windowsSDKLibVersion = *WinSdkVersion;
912 "Include", windowsSDKIncludeVersion,
915 "Include", windowsSDKIncludeVersion,
918 "Include", windowsSDKIncludeVersion,
921 llvm::VersionTuple Tuple;
922 if (!Tuple.tryParse(windowsSDKIncludeVersion) &&
923 Tuple.getSubminor().value_or(0) >= 17134) {
925 "Include", windowsSDKIncludeVersion,
941 const StringRef Paths[] = {
942 "C:/Program Files/Microsoft Visual Studio 10.0/VC/include",
943 "C:/Program Files/Microsoft Visual Studio 9.0/VC/include",
944 "C:/Program Files/Microsoft Visual Studio 9.0/VC/PlatformSDK/Include",
945 "C:/Program Files/Microsoft Visual Studio 8/VC/include",
946 "C:/Program Files/Microsoft Visual Studio 8/VC/PlatformSDK/Include"
1025 bool SupportsForcingFramePointer,
1026 const char *ExpandChar,
const OptTable &Opts) {
1027 assert(A->getOption().matches(options::OPT__SLASH_O));
1029 StringRef OptStr = A->getValue();
1030 for (
size_t I = 0, E = OptStr.size(); I != E; ++I) {
1031 const char &OptChar = *(OptStr.data() + I);
1041 if (&OptChar != ExpandChar) {
1045 if (OptChar ==
'd') {
1046 DAL.AddFlagArg(A, Opts.getOption(options::OPT_O0));
1048 if (OptChar ==
'1') {
1049 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O),
"s");
1050 }
else if (OptChar ==
'2' || OptChar ==
'x') {
1051 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
1052 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O),
"3");
1054 if (SupportsForcingFramePointer &&
1055 !DAL.hasArgNoClaim(options::OPT_fno_omit_frame_pointer))
1056 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fomit_frame_pointer));
1057 if (OptChar ==
'1' || OptChar ==
'2')
1058 DAL.AddFlagArg(A, Opts.getOption(options::OPT_ffunction_sections));
1062 if (I + 1 != E && isdigit(OptStr[I + 1])) {
1063 switch (OptStr[I + 1]) {
1065 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_inline));
1068 DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_hint_functions));
1072 DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_functions));
1082 if (I + 1 != E && OptStr[I + 1] ==
'-') {
1084 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_builtin));
1086 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
1090 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O),
"s");
1093 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O),
"3");
1096 bool OmitFramePointer =
true;
1097 if (I + 1 != E && OptStr[I + 1] ==
'-') {
1098 OmitFramePointer =
false;
1101 if (SupportsForcingFramePointer) {
1102 if (OmitFramePointer)
1104 Opts.getOption(options::OPT_fomit_frame_pointer));
1107 A, Opts.getOption(options::OPT_fno_omit_frame_pointer));