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"));
88 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles) &&
89 !
C.getDriver().IsCLMode() && !
C.getDriver().IsFlangMode()) {
90 CmdArgs.push_back(
"-defaultlib:libcmt");
91 CmdArgs.push_back(
"-defaultlib:oldnames");
99 if (
const Arg *A = Args.getLastArg(options::OPT__SLASH_diasdkdir,
100 options::OPT__SLASH_winsysroot)) {
105 if (A->getOption().getID() == options::OPT__SLASH_winsysroot)
106 llvm::sys::path::append(DIAPath,
"DIA SDK");
109 llvm::sys::path::append(DIAPath,
"lib",
110 llvm::archToLegacyVCArch(TC.getArch()));
111 CmdArgs.push_back(Args.MakeArgString(Twine(
"-libpath:") + DIAPath));
113 if (!llvm::sys::Process::GetEnv(
"LIB") ||
114 Args.hasArg(options::OPT__SLASH_vctoolsdir,
115 options::OPT__SLASH_vctoolsversion,
116 options::OPT__SLASH_winsysroot)) {
117 CmdArgs.push_back(Args.MakeArgString(
119 TC.getSubDirectoryPath(llvm::SubDirectoryType::Lib)));
120 CmdArgs.push_back(Args.MakeArgString(
122 TC.getSubDirectoryPath(llvm::SubDirectoryType::Lib,
"atlmfc")));
124 if (!llvm::sys::Process::GetEnv(
"LIB") ||
125 Args.hasArg(options::OPT__SLASH_winsdkdir,
126 options::OPT__SLASH_winsdkversion,
127 options::OPT__SLASH_winsysroot)) {
128 if (TC.useUniversalCRT()) {
129 std::string UniversalCRTLibPath;
130 if (TC.getUniversalCRTLibraryPath(Args, UniversalCRTLibPath))
132 Args.MakeArgString(Twine(
"-libpath:") + UniversalCRTLibPath));
134 std::string WindowsSdkLibPath;
135 if (TC.getWindowsSDKLibraryPath(Args, WindowsSdkLibPath))
137 Args.MakeArgString(std::string(
"-libpath:") + WindowsSdkLibPath));
140 if (!
C.getDriver().IsCLMode() && Args.hasArg(options::OPT_L))
141 for (
const auto &LibPath : Args.getAllArgValues(options::OPT_L))
142 CmdArgs.push_back(Args.MakeArgString(
"-libpath:" + LibPath));
144 if (
C.getDriver().IsFlangMode() &&
145 !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
146 TC.addFortranRuntimeLibraryPath(Args, CmdArgs);
147 TC.addFortranRuntimeLibs(Args, CmdArgs);
152 CmdArgs.push_back(
"/subsystem:console");
157 for (
const auto &LibPath : TC.getLibraryPaths()) {
158 if (TC.getVFS().exists(LibPath))
159 CmdArgs.push_back(Args.MakeArgString(
"-libpath:" + LibPath));
161 auto CRTPath = TC.getCompilerRTPath();
162 if (TC.getVFS().exists(CRTPath))
163 CmdArgs.push_back(Args.MakeArgString(
"-libpath:" + CRTPath));
165 CmdArgs.push_back(
"-nologo");
167 if (Args.hasArg(options::OPT_g_Group, options::OPT__SLASH_Z7))
168 CmdArgs.push_back(
"-debug");
172 if (Args.hasArg(options::OPT_fms_hotpatch, options::OPT__SLASH_hotpatch))
173 CmdArgs.push_back(
"-functionpadmin");
177 bool DefaultIncrementalLinkerCompatible =
178 C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment();
179 if (!Args.hasFlag(options::OPT_mincremental_linker_compatible,
180 options::OPT_mno_incremental_linker_compatible,
181 DefaultIncrementalLinkerCompatible))
182 CmdArgs.push_back(
"-Brepro");
184 bool DLL = Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd,
185 options::OPT_shared);
187 CmdArgs.push_back(Args.MakeArgString(
"-dll"));
190 llvm::sys::path::replace_extension(ImplibName,
"lib");
191 CmdArgs.push_back(Args.MakeArgString(std::string(
"-implib:") + ImplibName));
194 if (TC.getSanitizerArgs(Args).needsFuzzer()) {
195 if (!Args.hasArg(options::OPT_shared))
197 Args.MakeArgString(std::string(
"-wholearchive:") +
198 TC.getCompilerRTArgString(Args,
"fuzzer")));
199 CmdArgs.push_back(Args.MakeArgString(
"-debug"));
202 CmdArgs.push_back(Args.MakeArgString(
"-incremental:no"));
205 if (TC.getSanitizerArgs(Args).needsAsanRt()) {
206 CmdArgs.push_back(Args.MakeArgString(
"-debug"));
207 CmdArgs.push_back(Args.MakeArgString(
"-incremental:no"));
208 CmdArgs.push_back(TC.getCompilerRTArgString(Args,
"asan_dynamic"));
209 auto defines = Args.getAllArgValues(options::OPT_D);
210 if (Args.hasArg(options::OPT__SLASH_MD, options::OPT__SLASH_MDd) ||
211 llvm::is_contained(defines,
"_DLL")) {
214 CmdArgs.push_back(Args.MakeArgString(
215 TC.getArch() == llvm::Triple::x86
216 ?
"-include:___asan_seh_interceptor"
217 :
"-include:__asan_seh_interceptor"));
220 CmdArgs.push_back(Args.MakeArgString(
221 std::string(
"-wholearchive:") +
222 TC.getCompilerRT(Args,
"asan_dynamic_runtime_thunk")));
226 CmdArgs.push_back(Args.MakeArgString(
227 std::string(
"-wholearchive:") +
228 TC.getCompilerRT(Args,
"asan_static_runtime_thunk")));
232 if (
C.getDriver().isUsingLTO()) {
234 CmdArgs.push_back(Args.MakeArgString(std::string(
"-lto-sample-profile:") +
237 Args.AddAllArgValues(CmdArgs, options::OPT__SLASH_link);
240 for (
const Arg *A : Args.filtered(options::OPT__SLASH_guard)) {
241 StringRef GuardArgs = A->getValue();
242 if (GuardArgs.equals_insensitive(
"cf") ||
243 GuardArgs.equals_insensitive(
"cf,nochecks")) {
245 CmdArgs.push_back(
"-guard:cf");
246 }
else if (GuardArgs.equals_insensitive(
"cf-")) {
247 CmdArgs.push_back(
"-guard:cf-");
248 }
else if (GuardArgs.equals_insensitive(
"ehcont")) {
249 CmdArgs.push_back(
"-guard:ehcont");
250 }
else if (GuardArgs.equals_insensitive(
"ehcont-")) {
251 CmdArgs.push_back(
"-guard:ehcont-");
255 if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
256 options::OPT_fno_openmp,
false)) {
257 CmdArgs.push_back(
"-nodefaultlib:vcomp.lib");
258 CmdArgs.push_back(
"-nodefaultlib:vcompd.lib");
259 CmdArgs.push_back(Args.MakeArgString(std::string(
"-libpath:") +
260 TC.getDriver().Dir +
"/../lib"));
261 switch (TC.getDriver().getOpenMPRuntime(Args)) {
263 CmdArgs.push_back(
"-defaultlib:libomp.lib");
266 CmdArgs.push_back(
"-defaultlib:libiomp5md.lib");
278 if (!Args.hasArg(options::OPT_nostdlib)) {
282 StringRef
Linker = Args.getLastArgValue(options::OPT_fuse_ld_EQ,
283 TC.getDriver().getPreferredLinker());
287 else if (
Linker.equals_insensitive(
"lld"))
290 if (
Linker ==
"lld-link") {
291 for (Arg *A : Args.filtered(options::OPT_vfsoverlay))
293 Args.MakeArgString(std::string(
"/vfsoverlay:") + A->getValue()));
295 if (
C.getDriver().isUsingLTO() &&
296 Args.hasFlag(options::OPT_gsplit_dwarf, options::OPT_gno_split_dwarf,
298 CmdArgs.push_back(Args.MakeArgString(Twine(
"/dwodir:") +
303 for (
const auto &Input : Inputs) {
304 if (Input.isFilename()) {
305 CmdArgs.push_back(Input.getFilename());
309 const Arg &A = Input.getInputArg();
312 if (A.getOption().matches(options::OPT_l)) {
313 StringRef Lib = A.getValue();
314 const char *LinkLibArg;
315 if (Lib.ends_with(
".lib"))
316 LinkLibArg = Args.MakeArgString(Lib);
318 LinkLibArg = Args.MakeArgString(Lib +
".lib");
319 CmdArgs.push_back(LinkLibArg);
325 A.renderAsInput(Args, CmdArgs);
330 TC.addProfileRTLibs(Args, CmdArgs);
332 std::vector<const char *> Environment;
337 if (
Linker.equals_insensitive(
"link")) {
343 if (!TC.FoundMSVCInstall() && !
canExecute(TC.getVFS(), linkPath)) {
345 ClPath = TC.GetProgramPath(
"cl.exe");
347 linkPath = llvm::sys::path::parent_path(ClPath);
348 llvm::sys::path::append(linkPath,
"link.exe");
350 C.getDriver().Diag(clang::diag::warn_drv_msvc_not_found);
352 C.getDriver().Diag(clang::diag::warn_drv_msvc_not_found);
358 if (TC.getSanitizerArgs(Args).needsAsanRt())
359 CmdArgs.push_back(
"/INFERASANLIBS:NO");
368 if (TC.getIsVS2017OrNewer() &&
369 llvm::Triple(llvm::sys::getProcessTriple()).getArch() != TC.getArch()) {
370 auto HostArch = llvm::Triple(llvm::sys::getProcessTriple()).getArch();
373 std::unique_ptr<wchar_t[], decltype(&FreeEnvironmentStringsW)>(
374 GetEnvironmentStringsW(), FreeEnvironmentStringsW);
376 goto SkipSettingEnvironment;
379 size_t EnvBlockLen = 0;
380 while (EnvBlockWide[EnvBlockLen] != L
'\0') {
382 EnvBlockLen += std::wcslen(&EnvBlockWide[EnvBlockLen]) +
387 std::string EnvBlock;
388 if (!llvm::convertUTF16ToUTF8String(
390 EnvBlockLen *
sizeof(EnvBlockWide[0])),
392 goto SkipSettingEnvironment;
394 Environment.reserve(EnvCount);
399 for (
const char *Cursor = EnvBlock.data(); *Cursor !=
'\0';) {
400 llvm::StringRef EnvVar(Cursor);
401 if (EnvVar.starts_with_insensitive(
"path=")) {
402 constexpr size_t PrefixLen = 5;
403 Environment.push_back(Args.MakeArgString(
404 EnvVar.substr(0, PrefixLen) +
405 TC.getSubDirectoryPath(llvm::SubDirectoryType::Bin) +
406 llvm::Twine(llvm::sys::EnvPathSeparator) +
407 TC.getSubDirectoryPath(llvm::SubDirectoryType::Bin, HostArch) +
408 (EnvVar.size() > PrefixLen
409 ? llvm::Twine(llvm::sys::EnvPathSeparator) +
410 EnvVar.substr(PrefixLen)
413 Environment.push_back(Args.MakeArgString(EnvVar));
415 Cursor += EnvVar.size() + 1 ;
418 SkipSettingEnvironment:;
421 linkPath = TC.GetProgramPath(
Linker.str().c_str());
424 auto LinkCmd = std::make_unique<Command>(
426 Args.MakeArgString(linkPath), CmdArgs, Inputs, Output);
427 if (!Environment.empty())
428 LinkCmd->setEnvironment(Environment);
429 C.addCommand(std::move(LinkCmd));
651 ArgStringList &CC1Args)
const {
652 if (DriverArgs.hasArg(options::OPT_nostdinc))
655 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
661 for (
const auto &Path : DriverArgs.getAllArgValues(options::OPT__SLASH_imsvc))
664 auto AddSystemIncludesFromEnv = [&](StringRef Var) ->
bool {
665 if (
auto Val = llvm::sys::Process::GetEnv(Var)) {
667 StringRef(*Val).split(Dirs,
";", -1,
false);
677 for (
const auto &Var :
678 DriverArgs.getAllArgValues(options::OPT__SLASH_external_env)) {
679 AddSystemIncludesFromEnv(Var);
683 if (
const Arg *A = DriverArgs.getLastArg(options::OPT__SLASH_diasdkdir,
684 options::OPT__SLASH_winsysroot)) {
689 if (A->getOption().getID() == options::OPT__SLASH_winsysroot)
690 llvm::sys::path::append(DIASDKPath,
"DIA SDK");
695 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
701 if (!DriverArgs.hasArg(
702 options::OPT__SLASH_vctoolsdir, options::OPT__SLASH_vctoolsversion,
703 options::OPT__SLASH_winsysroot, options::OPT__SLASH_winsdkdir,
704 options::OPT__SLASH_winsdkversion)) {
705 bool Found = AddSystemIncludesFromEnv(
"INCLUDE");
706 Found |= AddSystemIncludesFromEnv(
"EXTERNAL_INCLUDE");
713 if (!VCToolChainPath.empty()) {
721 std::string UniversalCRTSdkPath;
722 std::string UCRTVersion;
723 if (llvm::getUniversalCRTSdkDir(
getVFS(), WinSdkDir, WinSdkVersion,
724 WinSysRoot, UniversalCRTSdkPath,
726 if (!(WinSdkDir.has_value() || WinSysRoot.has_value()) &&
727 WinSdkVersion.has_value())
728 UCRTVersion = *WinSdkVersion;
730 "Include", UCRTVersion,
"ucrt");
734 std::string WindowsSDKDir;
736 std::string windowsSDKIncludeVersion;
737 std::string windowsSDKLibVersion;
738 if (llvm::getWindowsSDKDir(
getVFS(), WinSdkDir, WinSdkVersion, WinSysRoot,
739 WindowsSDKDir, major, windowsSDKIncludeVersion,
740 windowsSDKLibVersion)) {
742 if (!(WinSdkDir.has_value() || WinSysRoot.has_value()) &&
743 WinSdkVersion.has_value())
744 windowsSDKIncludeVersion = windowsSDKLibVersion = *WinSdkVersion;
749 "Include", windowsSDKIncludeVersion,
752 "Include", windowsSDKIncludeVersion,
755 "Include", windowsSDKIncludeVersion,
758 llvm::VersionTuple Tuple;
759 if (!Tuple.tryParse(windowsSDKIncludeVersion) &&
760 Tuple.getSubminor().value_or(0) >= 17134) {
762 "Include", windowsSDKIncludeVersion,
778 const StringRef Paths[] = {
779 "C:/Program Files/Microsoft Visual Studio 10.0/VC/include",
780 "C:/Program Files/Microsoft Visual Studio 9.0/VC/include",
781 "C:/Program Files/Microsoft Visual Studio 9.0/VC/PlatformSDK/Include",
782 "C:/Program Files/Microsoft Visual Studio 8/VC/include",
783 "C:/Program Files/Microsoft Visual Studio 8/VC/PlatformSDK/Include"
850 bool SupportsForcingFramePointer,
851 const char *ExpandChar,
const OptTable &Opts) {
852 assert(A->getOption().matches(options::OPT__SLASH_O));
854 StringRef OptStr = A->getValue();
855 for (
size_t I = 0, E = OptStr.size(); I != E; ++I) {
856 const char &OptChar = *(OptStr.data() + I);
866 if (&OptChar != ExpandChar) {
870 if (OptChar ==
'd') {
871 DAL.AddFlagArg(A, Opts.getOption(options::OPT_O0));
873 if (OptChar ==
'1') {
874 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O),
"s");
875 }
else if (OptChar ==
'2' || OptChar ==
'x') {
876 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
877 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O),
"3");
879 if (SupportsForcingFramePointer &&
880 !DAL.hasArgNoClaim(options::OPT_fno_omit_frame_pointer))
881 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fomit_frame_pointer));
882 if (OptChar ==
'1' || OptChar ==
'2')
883 DAL.AddFlagArg(A, Opts.getOption(options::OPT_ffunction_sections));
887 if (I + 1 != E && isdigit(OptStr[I + 1])) {
888 switch (OptStr[I + 1]) {
890 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_inline));
893 DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_hint_functions));
897 DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_functions));
907 if (I + 1 != E && OptStr[I + 1] ==
'-') {
909 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_builtin));
911 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
915 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O),
"s");
918 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O),
"3");
921 bool OmitFramePointer =
true;
922 if (I + 1 != E && OptStr[I + 1] ==
'-') {
923 OmitFramePointer =
false;
926 if (SupportsForcingFramePointer) {
927 if (OmitFramePointer)
929 Opts.getOption(options::OPT_fomit_frame_pointer));
932 A, Opts.getOption(options::OPT_fno_omit_frame_pointer));