clang 18.0.0git
MinGW.cpp
Go to the documentation of this file.
1//===--- MinGW.cpp - MinGWToolChain Implementation ------------------------===//
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 "MinGW.h"
10#include "CommonArgs.h"
11#include "clang/Config/config.h"
13#include "clang/Driver/Driver.h"
18#include "llvm/Option/ArgList.h"
19#include "llvm/Support/FileSystem.h"
20#include "llvm/Support/Path.h"
21#include "llvm/Support/VirtualFileSystem.h"
22#include <system_error>
23
24using namespace clang::diag;
25using namespace clang::driver;
26using namespace clang;
27using namespace llvm::opt;
28
29/// MinGW Tools
31 const InputInfo &Output,
32 const InputInfoList &Inputs,
33 const ArgList &Args,
34 const char *LinkingOutput) const {
35 claimNoWarnArgs(Args);
36 ArgStringList CmdArgs;
37
38 if (getToolChain().getArch() == llvm::Triple::x86) {
39 CmdArgs.push_back("--32");
40 } else if (getToolChain().getArch() == llvm::Triple::x86_64) {
41 CmdArgs.push_back("--64");
42 }
43
44 Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
45
46 CmdArgs.push_back("-o");
47 CmdArgs.push_back(Output.getFilename());
48
49 for (const auto &II : Inputs)
50 CmdArgs.push_back(II.getFilename());
51
52 const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
53 C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
54 Exec, CmdArgs, Inputs, Output));
55
56 if (Args.hasArg(options::OPT_gsplit_dwarf))
57 SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output,
58 SplitDebugName(JA, Args, Inputs[0], Output));
59}
60
61void tools::MinGW::Linker::AddLibGCC(const ArgList &Args,
62 ArgStringList &CmdArgs) const {
63 if (Args.hasArg(options::OPT_mthreads))
64 CmdArgs.push_back("-lmingwthrd");
65 CmdArgs.push_back("-lmingw32");
66
67 // Make use of compiler-rt if --rtlib option is used
68 ToolChain::RuntimeLibType RLT = getToolChain().GetRuntimeLibType(Args);
69 if (RLT == ToolChain::RLT_Libgcc) {
70 bool Static = Args.hasArg(options::OPT_static_libgcc) ||
71 Args.hasArg(options::OPT_static);
72 bool Shared = Args.hasArg(options::OPT_shared);
73 bool CXX = getToolChain().getDriver().CCCIsCXX();
74
75 if (Static || (!CXX && !Shared)) {
76 CmdArgs.push_back("-lgcc");
77 CmdArgs.push_back("-lgcc_eh");
78 } else {
79 CmdArgs.push_back("-lgcc_s");
80 CmdArgs.push_back("-lgcc");
81 }
82 } else {
83 AddRunTimeLibs(getToolChain(), getToolChain().getDriver(), CmdArgs, Args);
84 }
85
86 CmdArgs.push_back("-lmoldname");
87 CmdArgs.push_back("-lmingwex");
88 for (auto Lib : Args.getAllArgValues(options::OPT_l))
89 if (StringRef(Lib).startswith("msvcr") ||
90 StringRef(Lib).startswith("ucrt") ||
91 StringRef(Lib).startswith("crtdll"))
92 return;
93 CmdArgs.push_back("-lmsvcrt");
94}
95
97 const InputInfo &Output,
98 const InputInfoList &Inputs,
99 const ArgList &Args,
100 const char *LinkingOutput) const {
101 const ToolChain &TC = getToolChain();
102 const Driver &D = TC.getDriver();
103 const SanitizerArgs &Sanitize = TC.getSanitizerArgs(Args);
104
105 ArgStringList CmdArgs;
106
107 // Silence warning for "clang -g foo.o -o foo"
108 Args.ClaimAllArgs(options::OPT_g_Group);
109 // and "clang -emit-llvm foo.o -o foo"
110 Args.ClaimAllArgs(options::OPT_emit_llvm);
111 // and for "clang -w foo.o -o foo". Other warning options are already
112 // handled somewhere else.
113 Args.ClaimAllArgs(options::OPT_w);
114
115 if (!D.SysRoot.empty())
116 CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
117
118 if (Args.hasArg(options::OPT_s))
119 CmdArgs.push_back("-s");
120
121 CmdArgs.push_back("-m");
122 switch (TC.getArch()) {
123 case llvm::Triple::x86:
124 CmdArgs.push_back("i386pe");
125 break;
126 case llvm::Triple::x86_64:
127 CmdArgs.push_back("i386pep");
128 break;
129 case llvm::Triple::arm:
130 case llvm::Triple::thumb:
131 // FIXME: this is incorrect for WinCE
132 CmdArgs.push_back("thumb2pe");
133 break;
134 case llvm::Triple::aarch64:
135 CmdArgs.push_back("arm64pe");
136 break;
137 default:
138 D.Diag(diag::err_target_unknown_triple) << TC.getEffectiveTriple().str();
139 }
140
141 Arg *SubsysArg =
142 Args.getLastArg(options::OPT_mwindows, options::OPT_mconsole);
143 if (SubsysArg && SubsysArg->getOption().matches(options::OPT_mwindows)) {
144 CmdArgs.push_back("--subsystem");
145 CmdArgs.push_back("windows");
146 } else if (SubsysArg &&
147 SubsysArg->getOption().matches(options::OPT_mconsole)) {
148 CmdArgs.push_back("--subsystem");
149 CmdArgs.push_back("console");
150 }
151
152 if (Args.hasArg(options::OPT_mdll))
153 CmdArgs.push_back("--dll");
154 else if (Args.hasArg(options::OPT_shared))
155 CmdArgs.push_back("--shared");
156 if (Args.hasArg(options::OPT_static))
157 CmdArgs.push_back("-Bstatic");
158 else
159 CmdArgs.push_back("-Bdynamic");
160 if (Args.hasArg(options::OPT_mdll) || Args.hasArg(options::OPT_shared)) {
161 CmdArgs.push_back("-e");
162 if (TC.getArch() == llvm::Triple::x86)
163 CmdArgs.push_back("_DllMainCRTStartup@12");
164 else
165 CmdArgs.push_back("DllMainCRTStartup");
166 CmdArgs.push_back("--enable-auto-image-base");
167 }
168
169 if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
170 CmdArgs.push_back("--no-demangle");
171
172 if (!Args.hasFlag(options::OPT_fauto_import, options::OPT_fno_auto_import,
173 true))
174 CmdArgs.push_back("--disable-auto-import");
175
176 if (Arg *A = Args.getLastArg(options::OPT_mguard_EQ)) {
177 StringRef GuardArgs = A->getValue();
178 if (GuardArgs == "none")
179 CmdArgs.push_back("--no-guard-cf");
180 else if (GuardArgs == "cf" || GuardArgs == "cf-nochecks")
181 CmdArgs.push_back("--guard-cf");
182 else
183 D.Diag(diag::err_drv_unsupported_option_argument)
184 << A->getSpelling() << GuardArgs;
185 }
186
187 CmdArgs.push_back("-o");
188 const char *OutputFile = Output.getFilename();
189 // GCC implicitly adds an .exe extension if it is given an output file name
190 // that lacks an extension.
191 // GCC used to do this only when the compiler itself runs on windows, but
192 // since GCC 8 it does the same when cross compiling as well.
193 if (!llvm::sys::path::has_extension(OutputFile)) {
194 CmdArgs.push_back(Args.MakeArgString(Twine(OutputFile) + ".exe"));
195 OutputFile = CmdArgs.back();
196 } else
197 CmdArgs.push_back(OutputFile);
198
199 // FIXME: add -N, -n flags
200 Args.AddLastArg(CmdArgs, options::OPT_r);
201 Args.AddLastArg(CmdArgs, options::OPT_s);
202 Args.AddLastArg(CmdArgs, options::OPT_t);
203 Args.AddAllArgs(CmdArgs, options::OPT_u_Group);
204 Args.AddLastArg(CmdArgs, options::OPT_Z_Flag);
205
206 // Add asan_dynamic as the first import lib before other libs. This allows
207 // asan to be initialized as early as possible to increase its instrumentation
208 // coverage to include other user DLLs which has not been built with asan.
209 if (Sanitize.needsAsanRt() && !Args.hasArg(options::OPT_nostdlib) &&
210 !Args.hasArg(options::OPT_nodefaultlibs)) {
211 // MinGW always links against a shared MSVCRT.
212 CmdArgs.push_back(
213 TC.getCompilerRTArgString(Args, "asan_dynamic", ToolChain::FT_Shared));
214 }
215
216 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
217 if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_mdll)) {
218 CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("dllcrt2.o")));
219 } else {
220 if (Args.hasArg(options::OPT_municode))
221 CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crt2u.o")));
222 else
223 CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crt2.o")));
224 }
225 if (Args.hasArg(options::OPT_pg))
226 CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("gcrt2.o")));
227 CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crtbegin.o")));
228 }
229
230 Args.AddAllArgs(CmdArgs, options::OPT_L);
231 TC.AddFilePathLibArgs(Args, CmdArgs);
232
233 // Add the compiler-rt library directories if they exist to help
234 // the linker find the various sanitizer, builtin, and profiling runtimes.
235 for (const auto &LibPath : TC.getLibraryPaths()) {
236 if (TC.getVFS().exists(LibPath))
237 CmdArgs.push_back(Args.MakeArgString("-L" + LibPath));
238 }
239 auto CRTPath = TC.getCompilerRTPath();
240 if (TC.getVFS().exists(CRTPath))
241 CmdArgs.push_back(Args.MakeArgString("-L" + CRTPath));
242
243 AddLinkerInputs(TC, Inputs, Args, CmdArgs, JA);
244
245 if (D.isUsingLTO()) {
246 assert(!Inputs.empty() && "Must have at least one input.");
247 addLTOOptions(TC, Args, CmdArgs, Output, Inputs[0],
248 D.getLTOMode() == LTOK_Thin);
249 }
250
251 if (C.getDriver().IsFlangMode()) {
252 addFortranRuntimeLibraryPath(TC, Args, CmdArgs);
253 addFortranRuntimeLibs(TC, CmdArgs);
254 }
255
256 // TODO: Add profile stuff here
257
258 if (TC.ShouldLinkCXXStdlib(Args)) {
259 bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
260 !Args.hasArg(options::OPT_static);
261 if (OnlyLibstdcxxStatic)
262 CmdArgs.push_back("-Bstatic");
263 TC.AddCXXStdlibLibArgs(Args, CmdArgs);
264 if (OnlyLibstdcxxStatic)
265 CmdArgs.push_back("-Bdynamic");
266 }
267
268 bool HasWindowsApp = false;
269 for (auto Lib : Args.getAllArgValues(options::OPT_l)) {
270 if (Lib == "windowsapp") {
271 HasWindowsApp = true;
272 break;
273 }
274 }
275
276 if (!Args.hasArg(options::OPT_nostdlib)) {
277 if (!Args.hasArg(options::OPT_nodefaultlibs)) {
278 if (Args.hasArg(options::OPT_static))
279 CmdArgs.push_back("--start-group");
280
281 if (Args.hasArg(options::OPT_fstack_protector) ||
282 Args.hasArg(options::OPT_fstack_protector_strong) ||
283 Args.hasArg(options::OPT_fstack_protector_all)) {
284 CmdArgs.push_back("-lssp_nonshared");
285 CmdArgs.push_back("-lssp");
286 }
287
288 if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
289 options::OPT_fno_openmp, false)) {
290 switch (TC.getDriver().getOpenMPRuntime(Args)) {
292 CmdArgs.push_back("-lomp");
293 break;
295 CmdArgs.push_back("-liomp5md");
296 break;
298 CmdArgs.push_back("-lgomp");
299 break;
301 // Already diagnosed.
302 break;
303 }
304 }
305
306 AddLibGCC(Args, CmdArgs);
307
308 if (Args.hasArg(options::OPT_pg))
309 CmdArgs.push_back("-lgmon");
310
311 if (Args.hasArg(options::OPT_pthread))
312 CmdArgs.push_back("-lpthread");
313
314 if (Sanitize.needsAsanRt()) {
315 // MinGW always links against a shared MSVCRT.
316 CmdArgs.push_back(TC.getCompilerRTArgString(Args, "asan_dynamic",
318 CmdArgs.push_back(
319 TC.getCompilerRTArgString(Args, "asan_dynamic_runtime_thunk"));
320 CmdArgs.push_back("--require-defined");
321 CmdArgs.push_back(TC.getArch() == llvm::Triple::x86
322 ? "___asan_seh_interceptor"
323 : "__asan_seh_interceptor");
324 // Make sure the linker consider all object files from the dynamic
325 // runtime thunk.
326 CmdArgs.push_back("--whole-archive");
327 CmdArgs.push_back(
328 TC.getCompilerRTArgString(Args, "asan_dynamic_runtime_thunk"));
329 CmdArgs.push_back("--no-whole-archive");
330 }
331
332 TC.addProfileRTLibs(Args, CmdArgs);
333
334 if (!HasWindowsApp) {
335 // Add system libraries. If linking to libwindowsapp.a, that import
336 // library replaces all these and we shouldn't accidentally try to
337 // link to the normal desktop mode dlls.
338 if (Args.hasArg(options::OPT_mwindows)) {
339 CmdArgs.push_back("-lgdi32");
340 CmdArgs.push_back("-lcomdlg32");
341 }
342 CmdArgs.push_back("-ladvapi32");
343 CmdArgs.push_back("-lshell32");
344 CmdArgs.push_back("-luser32");
345 CmdArgs.push_back("-lkernel32");
346 }
347
348 if (Args.hasArg(options::OPT_static)) {
349 CmdArgs.push_back("--end-group");
350 } else {
351 AddLibGCC(Args, CmdArgs);
352 if (!HasWindowsApp)
353 CmdArgs.push_back("-lkernel32");
354 }
355 }
356
357 if (!Args.hasArg(options::OPT_nostartfiles)) {
358 // Add crtfastmath.o if available and fast math is enabled.
359 TC.addFastMathRuntimeIfAvailable(Args, CmdArgs);
360
361 CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crtend.o")));
362 }
363 }
364 const char *Exec = Args.MakeArgString(TC.GetLinkerPath());
365 C.addCommand(std::make_unique<Command>(JA, *this,
367 Exec, CmdArgs, Inputs, Output));
368}
369
370static bool isCrossCompiling(const llvm::Triple &T, bool RequireArchMatch) {
371 llvm::Triple HostTriple(llvm::Triple::normalize(LLVM_HOST_TRIPLE));
372 if (HostTriple.getOS() != llvm::Triple::Win32)
373 return true;
374 if (RequireArchMatch && HostTriple.getArch() != T.getArch())
375 return true;
376 return false;
377}
378
379// Simplified from Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple.
380static bool findGccVersion(StringRef LibDir, std::string &GccLibDir,
381 std::string &Ver,
384 std::error_code EC;
385 for (llvm::sys::fs::directory_iterator LI(LibDir, EC), LE; !EC && LI != LE;
386 LI = LI.increment(EC)) {
387 StringRef VersionText = llvm::sys::path::filename(LI->path());
388 auto CandidateVersion =
390 if (CandidateVersion.Major == -1)
391 continue;
392 if (CandidateVersion <= Version)
393 continue;
394 Version = CandidateVersion;
395 Ver = std::string(VersionText);
396 GccLibDir = LI->path();
397 }
398 return Ver.size();
399}
400
401static llvm::Triple getLiteralTriple(const Driver &D, const llvm::Triple &T) {
402 llvm::Triple LiteralTriple(D.getTargetTriple());
403 // The arch portion of the triple may be overridden by -m32/-m64.
404 LiteralTriple.setArchName(T.getArchName());
405 return LiteralTriple;
406}
407
408void toolchains::MinGW::findGccLibDir(const llvm::Triple &LiteralTriple) {
410 SubdirNames.emplace_back(LiteralTriple.str());
411 SubdirNames.emplace_back(getTriple().str());
412 SubdirNames.emplace_back(getTriple().getArchName());
413 SubdirNames.back() += "-w64-mingw32";
414 SubdirNames.emplace_back(getTriple().getArchName());
415 SubdirNames.back() += "-w64-mingw32ucrt";
416 SubdirNames.emplace_back("mingw32");
417 if (SubdirName.empty()) {
418 SubdirName = getTriple().getArchName();
419 SubdirName += "-w64-mingw32";
420 }
421 // lib: Arch Linux, Ubuntu, Windows
422 // lib64: openSUSE Linux
423 for (StringRef CandidateLib : {"lib", "lib64"}) {
424 for (StringRef CandidateSysroot : SubdirNames) {
426 llvm::sys::path::append(LibDir, CandidateLib, "gcc", CandidateSysroot);
427 if (findGccVersion(LibDir, GccLibDir, Ver, GccVer)) {
428 SubdirName = std::string(CandidateSysroot);
429 return;
430 }
431 }
432 }
433}
434
435static llvm::ErrorOr<std::string> findGcc(const llvm::Triple &LiteralTriple,
436 const llvm::Triple &T) {
438 Gccs.emplace_back(LiteralTriple.str());
439 Gccs.back() += "-gcc";
440 Gccs.emplace_back(T.str());
441 Gccs.back() += "-gcc";
442 Gccs.emplace_back(T.getArchName());
443 Gccs.back() += "-w64-mingw32-gcc";
444 Gccs.emplace_back(T.getArchName());
445 Gccs.back() += "-w64-mingw32ucrt-gcc";
446 Gccs.emplace_back("mingw32-gcc");
447 // Please do not add "gcc" here
448 for (StringRef CandidateGcc : Gccs)
449 if (llvm::ErrorOr<std::string> GPPName = llvm::sys::findProgramByName(CandidateGcc))
450 return GPPName;
451 return make_error_code(std::errc::no_such_file_or_directory);
452}
453
454static llvm::ErrorOr<std::string>
455findClangRelativeSysroot(const Driver &D, const llvm::Triple &LiteralTriple,
456 const llvm::Triple &T, std::string &SubdirName) {
458 Subdirs.emplace_back(LiteralTriple.str());
459 Subdirs.emplace_back(T.str());
460 Subdirs.emplace_back(T.getArchName());
461 Subdirs.back() += "-w64-mingw32";
462 Subdirs.emplace_back(T.getArchName());
463 Subdirs.back() += "-w64-mingw32ucrt";
464 StringRef ClangRoot = llvm::sys::path::parent_path(D.getInstalledDir());
465 StringRef Sep = llvm::sys::path::get_separator();
466 for (StringRef CandidateSubdir : Subdirs) {
467 if (llvm::sys::fs::is_directory(ClangRoot + Sep + CandidateSubdir)) {
468 SubdirName = std::string(CandidateSubdir);
469 return (ClangRoot + Sep + CandidateSubdir).str();
470 }
471 }
472 return make_error_code(std::errc::no_such_file_or_directory);
473}
474
475toolchains::MinGW::MinGW(const Driver &D, const llvm::Triple &Triple,
476 const ArgList &Args)
477 : ToolChain(D, Triple, Args), CudaInstallation(D, Triple, Args),
478 RocmInstallation(D, Triple, Args) {
479 getProgramPaths().push_back(getDriver().getInstalledDir());
480
481 // The sequence for detecting a sysroot here should be kept in sync with
482 // the testTriple function below.
483 llvm::Triple LiteralTriple = getLiteralTriple(D, getTriple());
484 if (getDriver().SysRoot.size())
486 // Look for <clang-bin>/../<triplet>; if found, use <clang-bin>/.. as the
487 // base as it could still be a base for a gcc setup with libgcc.
488 else if (llvm::ErrorOr<std::string> TargetSubdir = findClangRelativeSysroot(
489 getDriver(), LiteralTriple, getTriple(), SubdirName))
490 Base = std::string(llvm::sys::path::parent_path(TargetSubdir.get()));
491 else if (llvm::ErrorOr<std::string> GPPName =
492 findGcc(LiteralTriple, getTriple()))
493 Base = std::string(llvm::sys::path::parent_path(
494 llvm::sys::path::parent_path(GPPName.get())));
495 else
496 Base = std::string(
497 llvm::sys::path::parent_path(getDriver().getInstalledDir()));
498
499 Base += llvm::sys::path::get_separator();
500 findGccLibDir(LiteralTriple);
501 TripleDirName = SubdirName;
502 // GccLibDir must precede Base/lib so that the
503 // correct crtbegin.o ,cetend.o would be found.
504 getFilePaths().push_back(GccLibDir);
505
506 // openSUSE/Fedora
507 std::string CandidateSubdir = SubdirName + "/sys-root/mingw";
508 if (getDriver().getVFS().exists(Base + CandidateSubdir))
509 SubdirName = CandidateSubdir;
510
511 getFilePaths().push_back(
512 (Base + SubdirName + llvm::sys::path::get_separator() + "lib").str());
513
514 // Gentoo
515 getFilePaths().push_back(
516 (Base + SubdirName + llvm::sys::path::get_separator() + "mingw/lib").str());
517
518 // Only include <base>/lib if we're not cross compiling (not even for
519 // windows->windows to a different arch), or if the sysroot has been set
520 // (where we presume the user has pointed it at an arch specific
521 // subdirectory).
522 if (!::isCrossCompiling(getTriple(), /*RequireArchMatch=*/true) ||
523 getDriver().SysRoot.size())
524 getFilePaths().push_back(Base + "lib");
525
526 NativeLLVMSupport =
527 Args.getLastArgValue(options::OPT_fuse_ld_EQ, CLANG_DEFAULT_LINKER)
528 .equals_insensitive("lld");
529}
530
532 switch (AC) {
534 if (!Preprocessor)
535 Preprocessor.reset(new tools::gcc::Preprocessor(*this));
536 return Preprocessor.get();
538 if (!Compiler)
539 Compiler.reset(new tools::gcc::Compiler(*this));
540 return Compiler.get();
541 default:
542 return ToolChain::getTool(AC);
543 }
544}
545
547 return new tools::MinGW::Assembler(*this);
548}
549
551 return new tools::MinGW::Linker(*this);
552}
553
555 return NativeLLVMSupport;
556}
557
560 Arg *ExceptionArg = Args.getLastArg(options::OPT_fsjlj_exceptions,
561 options::OPT_fseh_exceptions,
562 options::OPT_fdwarf_exceptions);
563 if (ExceptionArg &&
564 ExceptionArg->getOption().matches(options::OPT_fseh_exceptions))
565 return UnwindTableLevel::Asynchronous;
566
567 if (getArch() == llvm::Triple::x86_64 || getArch() == llvm::Triple::arm ||
568 getArch() == llvm::Triple::thumb || getArch() == llvm::Triple::aarch64)
569 return UnwindTableLevel::Asynchronous;
570 return UnwindTableLevel::None;
571}
572
574 return getArch() == llvm::Triple::x86_64 ||
575 getArch() == llvm::Triple::aarch64;
576}
577
578bool toolchains::MinGW::isPIEDefault(const llvm::opt::ArgList &Args) const {
579 return false;
580}
581
582bool toolchains::MinGW::isPICDefaultForced() const { return true; }
583
584llvm::ExceptionHandling
585toolchains::MinGW::GetExceptionModel(const ArgList &Args) const {
586 if (getArch() == llvm::Triple::x86_64 || getArch() == llvm::Triple::aarch64 ||
587 getArch() == llvm::Triple::arm || getArch() == llvm::Triple::thumb)
588 return llvm::ExceptionHandling::WinEH;
589 return llvm::ExceptionHandling::DwarfCFI;
590}
591
594 Res |= SanitizerKind::Address;
595 Res |= SanitizerKind::PointerCompare;
596 Res |= SanitizerKind::PointerSubtract;
597 Res |= SanitizerKind::Vptr;
598 return Res;
599}
600
601void toolchains::MinGW::AddCudaIncludeArgs(const ArgList &DriverArgs,
602 ArgStringList &CC1Args) const {
603 CudaInstallation.AddCudaIncludeArgs(DriverArgs, CC1Args);
604}
605
606void toolchains::MinGW::AddHIPIncludeArgs(const ArgList &DriverArgs,
607 ArgStringList &CC1Args) const {
608 RocmInstallation.AddHIPIncludeArgs(DriverArgs, CC1Args);
609}
610
611void toolchains::MinGW::printVerboseInfo(raw_ostream &OS) const {
612 CudaInstallation.print(OS);
613 RocmInstallation.print(OS);
614}
615
616// Include directories for various hosts:
617
618// Windows, mingw.org
619// c:\mingw\lib\gcc\mingw32\4.8.1\include\c++
620// c:\mingw\lib\gcc\mingw32\4.8.1\include\c++\mingw32
621// c:\mingw\lib\gcc\mingw32\4.8.1\include\c++\backward
622// c:\mingw\include
623// c:\mingw\mingw32\include
624
625// Windows, mingw-w64 mingw-builds
626// c:\mingw32\i686-w64-mingw32\include
627// c:\mingw32\i686-w64-mingw32\include\c++
628// c:\mingw32\i686-w64-mingw32\include\c++\i686-w64-mingw32
629// c:\mingw32\i686-w64-mingw32\include\c++\backward
630
631// Windows, mingw-w64 msys2
632// c:\msys64\mingw32\include
633// c:\msys64\mingw32\i686-w64-mingw32\include
634// c:\msys64\mingw32\include\c++\4.9.2
635// c:\msys64\mingw32\include\c++\4.9.2\i686-w64-mingw32
636// c:\msys64\mingw32\include\c++\4.9.2\backward
637
638// openSUSE
639// /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include/c++
640// /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include/c++/x86_64-w64-mingw32
641// /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include/c++/backward
642// /usr/x86_64-w64-mingw32/sys-root/mingw/include
643
644// Arch Linux
645// /usr/i686-w64-mingw32/include/c++/5.1.0
646// /usr/i686-w64-mingw32/include/c++/5.1.0/i686-w64-mingw32
647// /usr/i686-w64-mingw32/include/c++/5.1.0/backward
648// /usr/i686-w64-mingw32/include
649
650// Ubuntu
651// /usr/include/c++/4.8
652// /usr/include/c++/4.8/x86_64-w64-mingw32
653// /usr/include/c++/4.8/backward
654// /usr/x86_64-w64-mingw32/include
655
656// Fedora
657// /usr/x86_64-w64-mingw32ucrt/sys-root/mingw/include/c++/x86_64-w64-mingw32ucrt
658// /usr/x86_64-w64-mingw32ucrt/sys-root/mingw/include/c++/backward
659// /usr/x86_64-w64-mingw32ucrt/sys-root/mingw/include
660// /usr/lib/gcc/x86_64-w64-mingw32ucrt/12.2.1/include-fixed
661
662void toolchains::MinGW::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
663 ArgStringList &CC1Args) const {
664 if (DriverArgs.hasArg(options::OPT_nostdinc))
665 return;
666
667 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
668 SmallString<1024> P(getDriver().ResourceDir);
669 llvm::sys::path::append(P, "include");
670 addSystemInclude(DriverArgs, CC1Args, P.str());
671 }
672
673 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
674 return;
675
676 addSystemInclude(DriverArgs, CC1Args,
677 Base + SubdirName + llvm::sys::path::get_separator() +
678 "include");
679
680 // Gentoo
681 addSystemInclude(DriverArgs, CC1Args,
682 Base + SubdirName + llvm::sys::path::get_separator() + "usr/include");
683
684 // Only include <base>/include if we're not cross compiling (but do allow it
685 // if we're on Windows and building for Windows on another architecture),
686 // or if the sysroot has been set (where we presume the user has pointed it
687 // at an arch specific subdirectory).
688 if (!::isCrossCompiling(getTriple(), /*RequireArchMatch=*/false) ||
689 getDriver().SysRoot.size())
690 addSystemInclude(DriverArgs, CC1Args, Base + "include");
691}
692
694 const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args,
695 Action::OffloadKind DeviceOffloadKind) const {
696 if (Arg *A = DriverArgs.getLastArg(options::OPT_mguard_EQ)) {
697 StringRef GuardArgs = A->getValue();
698 if (GuardArgs == "none") {
699 // Do nothing.
700 } else if (GuardArgs == "cf") {
701 // Emit CFG instrumentation and the table of address-taken functions.
702 CC1Args.push_back("-cfguard");
703 } else if (GuardArgs == "cf-nochecks") {
704 // Emit only the table of address-taken functions.
705 CC1Args.push_back("-cfguard-no-checks");
706 } else {
707 getDriver().Diag(diag::err_drv_unsupported_option_argument)
708 << A->getSpelling() << GuardArgs;
709 }
710 }
711
712 if (Arg *A = DriverArgs.getLastArgNoClaim(options::OPT_mthreads))
713 A->ignoreTargetSpecific();
714}
715
717 const ArgList &DriverArgs, ArgStringList &CC1Args) const {
718 if (DriverArgs.hasArg(options::OPT_nostdinc, options::OPT_nostdlibinc,
719 options::OPT_nostdincxx))
720 return;
721
722 StringRef Slash = llvm::sys::path::get_separator();
723
724 switch (GetCXXStdlibType(DriverArgs)) {
726 std::string TargetDir = (Base + "include" + Slash + getTripleString() +
727 Slash + "c++" + Slash + "v1")
728 .str();
729 if (getDriver().getVFS().exists(TargetDir))
730 addSystemInclude(DriverArgs, CC1Args, TargetDir);
731 addSystemInclude(DriverArgs, CC1Args,
732 Base + SubdirName + Slash + "include" + Slash + "c++" +
733 Slash + "v1");
734 addSystemInclude(DriverArgs, CC1Args,
735 Base + "include" + Slash + "c++" + Slash + "v1");
736 break;
737 }
738
741 CppIncludeBases.emplace_back(Base);
742 llvm::sys::path::append(CppIncludeBases[0], SubdirName, "include", "c++");
743 CppIncludeBases.emplace_back(Base);
744 llvm::sys::path::append(CppIncludeBases[1], SubdirName, "include", "c++",
745 Ver);
746 CppIncludeBases.emplace_back(Base);
747 llvm::sys::path::append(CppIncludeBases[2], "include", "c++", Ver);
748 CppIncludeBases.emplace_back(GccLibDir);
749 llvm::sys::path::append(CppIncludeBases[3], "include", "c++");
750 CppIncludeBases.emplace_back(GccLibDir);
751 llvm::sys::path::append(CppIncludeBases[4], "include",
752 "g++-v" + GccVer.Text);
753 CppIncludeBases.emplace_back(GccLibDir);
754 llvm::sys::path::append(CppIncludeBases[5], "include",
755 "g++-v" + GccVer.MajorStr + "." + GccVer.MinorStr);
756 CppIncludeBases.emplace_back(GccLibDir);
757 llvm::sys::path::append(CppIncludeBases[6], "include",
758 "g++-v" + GccVer.MajorStr);
759 for (auto &CppIncludeBase : CppIncludeBases) {
760 addSystemInclude(DriverArgs, CC1Args, CppIncludeBase);
761 CppIncludeBase += Slash;
762 addSystemInclude(DriverArgs, CC1Args, CppIncludeBase + TripleDirName);
763 addSystemInclude(DriverArgs, CC1Args, CppIncludeBase + "backward");
764 }
765 break;
766 }
767}
768
769static bool testTriple(const Driver &D, const llvm::Triple &Triple,
770 const ArgList &Args) {
771 // If an explicit sysroot is set, that will be used and we shouldn't try to
772 // detect anything else.
773 std::string SubdirName;
774 if (D.SysRoot.size())
775 return true;
776 llvm::Triple LiteralTriple = getLiteralTriple(D, Triple);
777 if (llvm::ErrorOr<std::string> TargetSubdir =
778 findClangRelativeSysroot(D, LiteralTriple, Triple, SubdirName))
779 return true;
780 if (llvm::ErrorOr<std::string> GPPName = findGcc(LiteralTriple, Triple))
781 return true;
782 // If we neither found a colocated sysroot or a matching gcc executable,
783 // conclude that we can't know if this is the correct spelling of the triple.
784 return false;
785}
786
787static llvm::Triple adjustTriple(const Driver &D, const llvm::Triple &Triple,
788 const ArgList &Args) {
789 // First test if the original triple can find a sysroot with the triple
790 // name.
791 if (testTriple(D, Triple, Args))
792 return Triple;
794 // If not, test a couple other possible arch names that might be what was
795 // intended.
796 if (Triple.getArch() == llvm::Triple::x86) {
797 Archs.emplace_back("i386");
798 Archs.emplace_back("i586");
799 Archs.emplace_back("i686");
800 } else if (Triple.getArch() == llvm::Triple::arm ||
801 Triple.getArch() == llvm::Triple::thumb) {
802 Archs.emplace_back("armv7");
803 }
804 for (auto A : Archs) {
805 llvm::Triple TestTriple(Triple);
806 TestTriple.setArchName(A);
807 if (testTriple(D, TestTriple, Args))
808 return TestTriple;
809 }
810 // If none was found, just proceed with the original value.
811 return Triple;
812}
813
814void toolchains::MinGW::fixTripleArch(const Driver &D, llvm::Triple &Triple,
815 const ArgList &Args) {
816 if (Triple.getArch() == llvm::Triple::x86 ||
817 Triple.getArch() == llvm::Triple::arm ||
818 Triple.getArch() == llvm::Triple::thumb)
819 Triple = adjustTriple(D, Triple, Args);
820}
StringRef P
static llvm::Triple getLiteralTriple(const Driver &D, const llvm::Triple &T)
Definition: MinGW.cpp:401
static bool findGccVersion(StringRef LibDir, std::string &GccLibDir, std::string &Ver, toolchains::Generic_GCC::GCCVersion &Version)
Definition: MinGW.cpp:380
static bool testTriple(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
Definition: MinGW.cpp:769
static llvm::Triple adjustTriple(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
Definition: MinGW.cpp:787
static llvm::ErrorOr< std::string > findGcc(const llvm::Triple &LiteralTriple, const llvm::Triple &T)
Definition: MinGW.cpp:435
static llvm::ErrorOr< std::string > findClangRelativeSysroot(const Driver &D, const llvm::Triple &LiteralTriple, const llvm::Triple &T, std::string &SubdirName)
Definition: MinGW.cpp:455
static bool isCrossCompiling(const llvm::Triple &T, bool RequireArchMatch)
Definition: MinGW.cpp:370
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
Definition: Preprocessor.h:128
Compilation - A set of tasks to perform for a single driver invocation.
Definition: Compilation.h:45
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
Definition: Driver.h:77
std::string SysRoot
sysroot, if present
Definition: Driver.h:183
OpenMPRuntimeKind getOpenMPRuntime(const llvm::opt::ArgList &Args) const
Compute the desired OpenMP runtime from the flags provided.
Definition: Driver.cpp:728
DiagnosticBuilder Diag(unsigned DiagID) const
Definition: Driver.h:144
LTOKind getLTOMode(bool IsOffload=false) const
Get the specific kind of LTO being performed.
Definition: Driver.h:704
const char * getInstalledDir() const
Get the path to where the clang executable was installed.
Definition: Driver.h:417
bool isUsingLTO(bool IsOffload=false) const
Returns true if we are performing any kind of LTO.
Definition: Driver.h:699
@ OMPRT_IOMP5
The legacy name for the LLVM OpenMP runtime from when it was the Intel OpenMP runtime.
Definition: Driver.h:140
@ OMPRT_OMP
The LLVM OpenMP runtime.
Definition: Driver.h:130
@ OMPRT_Unknown
An unknown OpenMP runtime.
Definition: Driver.h:126
@ OMPRT_GOMP
The GNU OpenMP runtime.
Definition: Driver.h:135
std::string getTargetTriple() const
Definition: Driver.h:409
InputInfo - Wrapper for information about an input source.
Definition: InputInfo.h:22
const char * getFilename() const
Definition: InputInfo.h:83
ToolChain - Access to tools for a single platform.
Definition: ToolChain.h:92
const char * getCompilerRTArgString(const llvm::opt::ArgList &Args, StringRef Component, FileType Type=ToolChain::FT_Static) const
Definition: ToolChain.cpp:674
bool ShouldLinkCXXStdlib(const llvm::opt::ArgList &Args) const
Returns if the C++ standard library should be linked in.
Definition: ToolChain.cpp:1235
std::string GetFilePath(const char *Name) const
Definition: ToolChain.cpp:824
path_list & getFilePaths()
Definition: ToolChain.h:287
llvm::Triple::ArchType getArch() const
Definition: ToolChain.h:261
const Driver & getDriver() const
Definition: ToolChain.h:245
llvm::vfs::FileSystem & getVFS() const
Definition: ToolChain.cpp:132
bool addFastMathRuntimeIfAvailable(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const
AddFastMathRuntimeIfAvailable - If a runtime library exists that sets global flags for unsafe floatin...
Definition: ToolChain.cpp:1292
path_list & getProgramPaths()
Definition: ToolChain.h:290
const llvm::Triple & getEffectiveTriple() const
Get the toolchain's effective clang triple.
Definition: ToolChain.h:275
virtual void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const
AddCXXStdlibLibArgs - Add the system specific linker arguments to use for the given C++ standard libr...
Definition: ToolChain.cpp:1241
const llvm::Triple & getTriple() const
Definition: ToolChain.h:247
virtual void addProfileRTLibs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const
addProfileRTLibs - When -fprofile-instr-profile is specified, try to pass a suitable profile runtime ...
Definition: ToolChain.cpp:1037
virtual std::string getCompilerRTPath() const
Definition: ToolChain.cpp:597
std::string GetLinkerPath(bool *LinkerIsLLD=nullptr) const
Returns the linker path, respecting the -fuse-ld= argument to determine the linker suffix or name.
Definition: ToolChain.cpp:832
void AddFilePathLibArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const
AddFilePathLibArgs - Add each thing in getFilePaths() as a "-L" option.
Definition: ToolChain.cpp:1260
SanitizerArgs getSanitizerArgs(const llvm::opt::ArgList &JobArgs) const
Definition: ToolChain.cpp:274
path_list & getLibraryPaths()
Definition: ToolChain.h:284
virtual Tool * getTool(Action::ActionClass AC) const
Definition: ToolChain.cpp:508
virtual SanitizerMask getSupportedSanitizers() const
Return sanitizers which are available in this toolchain.
Definition: ToolChain.cpp:1308
virtual bool isCrossCompiling() const
Returns true if the toolchain is targeting a non-native architecture.
Definition: ToolChain.cpp:927
Tool - Information on a specific compilation tool.
Definition: Tool.h:32
const ToolChain & getToolChain() const
Definition: Tool.h:52
Tool * getTool(Action::ActionClass AC) const override
Definition: MinGW.cpp:531
llvm::ExceptionHandling GetExceptionModel(const llvm::opt::ArgList &Args) const override
GetExceptionModel - Return the tool chain exception model.
Definition: MinGW.cpp:585
void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, Action::OffloadKind DeviceOffloadKind) const override
Add options that need to be passed to cc1 for this target.
Definition: MinGW.cpp:693
SanitizerMask getSupportedSanitizers() const override
Return sanitizers which are available in this toolchain.
Definition: MinGW.cpp:592
Tool * buildAssembler() const override
Definition: MinGW.cpp:546
void printVerboseInfo(raw_ostream &OS) const override
Dispatch to the specific toolchain for verbose printing.
Definition: MinGW.cpp:611
Tool * buildLinker() const override
Definition: MinGW.cpp:550
void AddHIPIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override
Add arguments to use system-specific HIP includes.
Definition: MinGW.cpp:606
bool isPIEDefault(const llvm::opt::ArgList &Args) const override
Test whether this toolchain defaults to PIE.
Definition: MinGW.cpp:578
void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override
Add arguments to use system-specific CUDA includes.
Definition: MinGW.cpp:601
bool HasNativeLLVMSupport() const override
HasNativeLTOLinker - Check whether the linker and related tools have native LLVM support.
Definition: MinGW.cpp:554
bool isPICDefault() const override
Test whether this toolchain defaults to PIC.
Definition: MinGW.cpp:573
bool isPICDefaultForced() const override
Tests whether this toolchain forces its default for PIC, PIE or non-PIC.
Definition: MinGW.cpp:582
void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override
Add the clang cc1 arguments for system include paths.
Definition: MinGW.cpp:662
void AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override
AddClangCXXStdlibIncludeArgs - Add the clang -cc1 level arguments to set the include paths to use for...
Definition: MinGW.cpp:716
UnwindTableLevel getDefaultUnwindTableLevel(const llvm::opt::ArgList &Args) const override
How detailed should the unwind tables be by default.
Definition: MinGW.cpp:559
MinGW(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args)
Definition: MinGW.cpp:475
static void fixTripleArch(const Driver &D, llvm::Triple &Triple, const llvm::opt::ArgList &Args)
Definition: MinGW.cpp:814
void ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, const llvm::opt::ArgList &TCArgs, const char *LinkingOutput) const override
MinGW Tools.
Definition: MinGW.cpp:30
void ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, const llvm::opt::ArgList &TCArgs, const char *LinkingOutput) const override
ConstructJob - Construct jobs to perform the action JA, writing to Output and with Inputs,...
Definition: MinGW.cpp:96
const char * SplitDebugName(const JobAction &JA, const llvm::opt::ArgList &Args, const InputInfo &Input, const InputInfo &Output)
void AddRunTimeLibs(const ToolChain &TC, const Driver &D, llvm::opt::ArgStringList &CmdArgs, const llvm::opt::ArgList &Args)
void SplitDebugInfo(const ToolChain &TC, Compilation &C, const Tool &T, const JobAction &JA, const llvm::opt::ArgList &Args, const InputInfo &Output, const char *OutFile)
void addFortranRuntimeLibs(const ToolChain &TC, llvm::opt::ArgStringList &CmdArgs)
Adds Fortran runtime libraries to CmdArgs.
Definition: CommonArgs.cpp:948
void addFortranRuntimeLibraryPath(const ToolChain &TC, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs)
Adds the path for the Fortran runtime libraries to CmdArgs.
void addLTOOptions(const ToolChain &ToolChain, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, const InputInfo &Output, const InputInfo &Input, bool IsThinLTO)
void claimNoWarnArgs(const llvm::opt::ArgList &Args)
void AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, const JobAction &JA)
std::error_code make_error_code(BuildPreambleError Error)
@ C
Languages that the frontend can parse and compile.
static constexpr ResponseFileSupport None()
Returns a ResponseFileSupport indicating that response files are not supported.
Definition: Job.h:78
static constexpr ResponseFileSupport AtFileUTF8()
Definition: Job.h:85
Struct to store and manipulate GCC versions.
Definition: Gnu.h:162
static GCCVersion Parse(StringRef VersionText)
Parse a GCCVersion object out of a string of text.
Definition: Gnu.cpp:2006