File: | build/llvm-toolchain-snapshot-16~++20220904122748+c444af1c20b3/clang/lib/Driver/ToolChains/MinGW.cpp |
Warning: | line 180, column 5 Value stored to 'OutputFile' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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" |
12 | #include "clang/Driver/Compilation.h" |
13 | #include "clang/Driver/Driver.h" |
14 | #include "clang/Driver/DriverDiagnostic.h" |
15 | #include "clang/Driver/InputInfo.h" |
16 | #include "clang/Driver/Options.h" |
17 | #include "clang/Driver/SanitizerArgs.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 | |
24 | using namespace clang::diag; |
25 | using namespace clang::driver; |
26 | using namespace clang; |
27 | using namespace llvm::opt; |
28 | |
29 | /// MinGW Tools |
30 | void tools::MinGW::Assembler::ConstructJob(Compilation &C, const JobAction &JA, |
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 | |
61 | void 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 | |
96 | void tools::MinGW::Linker::ConstructJob(Compilation &C, const JobAction &JA, |
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 | llvm_unreachable("Unsupported target architecture.")::llvm::llvm_unreachable_internal("Unsupported target architecture." , "clang/lib/Driver/ToolChains/MinGW.cpp", 138); |
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 | CmdArgs.push_back("-o"); |
173 | const char *OutputFile = Output.getFilename(); |
174 | // GCC implicitly adds an .exe extension if it is given an output file name |
175 | // that lacks an extension. |
176 | // GCC used to do this only when the compiler itself runs on windows, but |
177 | // since GCC 8 it does the same when cross compiling as well. |
178 | if (!llvm::sys::path::has_extension(OutputFile)) { |
179 | CmdArgs.push_back(Args.MakeArgString(Twine(OutputFile) + ".exe")); |
180 | OutputFile = CmdArgs.back(); |
Value stored to 'OutputFile' is never read | |
181 | } else |
182 | CmdArgs.push_back(OutputFile); |
183 | |
184 | Args.AddAllArgs(CmdArgs, options::OPT_e); |
185 | // FIXME: add -N, -n flags |
186 | Args.AddLastArg(CmdArgs, options::OPT_r); |
187 | Args.AddLastArg(CmdArgs, options::OPT_s); |
188 | Args.AddLastArg(CmdArgs, options::OPT_t); |
189 | Args.AddAllArgs(CmdArgs, options::OPT_u_Group); |
190 | Args.AddLastArg(CmdArgs, options::OPT_Z_Flag); |
191 | |
192 | if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) { |
193 | if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_mdll)) { |
194 | CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("dllcrt2.o"))); |
195 | } else { |
196 | if (Args.hasArg(options::OPT_municode)) |
197 | CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crt2u.o"))); |
198 | else |
199 | CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crt2.o"))); |
200 | } |
201 | if (Args.hasArg(options::OPT_pg)) |
202 | CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("gcrt2.o"))); |
203 | CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crtbegin.o"))); |
204 | } |
205 | |
206 | Args.AddAllArgs(CmdArgs, options::OPT_L); |
207 | TC.AddFilePathLibArgs(Args, CmdArgs); |
208 | |
209 | // Add the compiler-rt library directories if they exist to help |
210 | // the linker find the various sanitizer, builtin, and profiling runtimes. |
211 | for (const auto &LibPath : TC.getLibraryPaths()) { |
212 | if (TC.getVFS().exists(LibPath)) |
213 | CmdArgs.push_back(Args.MakeArgString("-L" + LibPath)); |
214 | } |
215 | auto CRTPath = TC.getCompilerRTPath(); |
216 | if (TC.getVFS().exists(CRTPath)) |
217 | CmdArgs.push_back(Args.MakeArgString("-L" + CRTPath)); |
218 | |
219 | AddLinkerInputs(TC, Inputs, Args, CmdArgs, JA); |
220 | |
221 | if (C.getDriver().IsFlangMode()) { |
222 | addFortranRuntimeLibraryPath(TC, Args, CmdArgs); |
223 | addFortranRuntimeLibs(TC, CmdArgs); |
224 | } |
225 | |
226 | // TODO: Add profile stuff here |
227 | |
228 | if (TC.ShouldLinkCXXStdlib(Args)) { |
229 | bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) && |
230 | !Args.hasArg(options::OPT_static); |
231 | if (OnlyLibstdcxxStatic) |
232 | CmdArgs.push_back("-Bstatic"); |
233 | TC.AddCXXStdlibLibArgs(Args, CmdArgs); |
234 | if (OnlyLibstdcxxStatic) |
235 | CmdArgs.push_back("-Bdynamic"); |
236 | } |
237 | |
238 | bool HasWindowsApp = false; |
239 | for (auto Lib : Args.getAllArgValues(options::OPT_l)) { |
240 | if (Lib == "windowsapp") { |
241 | HasWindowsApp = true; |
242 | break; |
243 | } |
244 | } |
245 | |
246 | if (!Args.hasArg(options::OPT_nostdlib)) { |
247 | if (!Args.hasArg(options::OPT_nodefaultlibs)) { |
248 | if (Args.hasArg(options::OPT_static)) |
249 | CmdArgs.push_back("--start-group"); |
250 | |
251 | if (Args.hasArg(options::OPT_fstack_protector) || |
252 | Args.hasArg(options::OPT_fstack_protector_strong) || |
253 | Args.hasArg(options::OPT_fstack_protector_all)) { |
254 | CmdArgs.push_back("-lssp_nonshared"); |
255 | CmdArgs.push_back("-lssp"); |
256 | } |
257 | |
258 | if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ, |
259 | options::OPT_fno_openmp, false)) { |
260 | switch (TC.getDriver().getOpenMPRuntime(Args)) { |
261 | case Driver::OMPRT_OMP: |
262 | CmdArgs.push_back("-lomp"); |
263 | break; |
264 | case Driver::OMPRT_IOMP5: |
265 | CmdArgs.push_back("-liomp5md"); |
266 | break; |
267 | case Driver::OMPRT_GOMP: |
268 | CmdArgs.push_back("-lgomp"); |
269 | break; |
270 | case Driver::OMPRT_Unknown: |
271 | // Already diagnosed. |
272 | break; |
273 | } |
274 | } |
275 | |
276 | AddLibGCC(Args, CmdArgs); |
277 | |
278 | if (Args.hasArg(options::OPT_pg)) |
279 | CmdArgs.push_back("-lgmon"); |
280 | |
281 | if (Args.hasArg(options::OPT_pthread)) |
282 | CmdArgs.push_back("-lpthread"); |
283 | |
284 | if (Sanitize.needsAsanRt()) { |
285 | // MinGW always links against a shared MSVCRT. |
286 | CmdArgs.push_back(TC.getCompilerRTArgString(Args, "asan_dynamic", |
287 | ToolChain::FT_Shared)); |
288 | CmdArgs.push_back( |
289 | TC.getCompilerRTArgString(Args, "asan_dynamic_runtime_thunk")); |
290 | CmdArgs.push_back("--require-defined"); |
291 | CmdArgs.push_back(TC.getArch() == llvm::Triple::x86 |
292 | ? "___asan_seh_interceptor" |
293 | : "__asan_seh_interceptor"); |
294 | // Make sure the linker consider all object files from the dynamic |
295 | // runtime thunk. |
296 | CmdArgs.push_back("--whole-archive"); |
297 | CmdArgs.push_back( |
298 | TC.getCompilerRTArgString(Args, "asan_dynamic_runtime_thunk")); |
299 | CmdArgs.push_back("--no-whole-archive"); |
300 | } |
301 | |
302 | TC.addProfileRTLibs(Args, CmdArgs); |
303 | |
304 | if (!HasWindowsApp) { |
305 | // Add system libraries. If linking to libwindowsapp.a, that import |
306 | // library replaces all these and we shouldn't accidentally try to |
307 | // link to the normal desktop mode dlls. |
308 | if (Args.hasArg(options::OPT_mwindows)) { |
309 | CmdArgs.push_back("-lgdi32"); |
310 | CmdArgs.push_back("-lcomdlg32"); |
311 | } |
312 | CmdArgs.push_back("-ladvapi32"); |
313 | CmdArgs.push_back("-lshell32"); |
314 | CmdArgs.push_back("-luser32"); |
315 | CmdArgs.push_back("-lkernel32"); |
316 | } |
317 | |
318 | if (Args.hasArg(options::OPT_static)) { |
319 | CmdArgs.push_back("--end-group"); |
320 | } else { |
321 | AddLibGCC(Args, CmdArgs); |
322 | if (!HasWindowsApp) |
323 | CmdArgs.push_back("-lkernel32"); |
324 | } |
325 | } |
326 | |
327 | if (!Args.hasArg(options::OPT_nostartfiles)) { |
328 | // Add crtfastmath.o if available and fast math is enabled. |
329 | TC.addFastMathRuntimeIfAvailable(Args, CmdArgs); |
330 | |
331 | CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crtend.o"))); |
332 | } |
333 | } |
334 | const char *Exec = Args.MakeArgString(TC.GetLinkerPath()); |
335 | C.addCommand(std::make_unique<Command>(JA, *this, |
336 | ResponseFileSupport::AtFileUTF8(), |
337 | Exec, CmdArgs, Inputs, Output)); |
338 | } |
339 | |
340 | // Simplified from Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple. |
341 | static bool findGccVersion(StringRef LibDir, std::string &GccLibDir, |
342 | std::string &Ver, |
343 | toolchains::Generic_GCC::GCCVersion &Version) { |
344 | Version = toolchains::Generic_GCC::GCCVersion::Parse("0.0.0"); |
345 | std::error_code EC; |
346 | for (llvm::sys::fs::directory_iterator LI(LibDir, EC), LE; !EC && LI != LE; |
347 | LI = LI.increment(EC)) { |
348 | StringRef VersionText = llvm::sys::path::filename(LI->path()); |
349 | auto CandidateVersion = |
350 | toolchains::Generic_GCC::GCCVersion::Parse(VersionText); |
351 | if (CandidateVersion.Major == -1) |
352 | continue; |
353 | if (CandidateVersion <= Version) |
354 | continue; |
355 | Version = CandidateVersion; |
356 | Ver = std::string(VersionText); |
357 | GccLibDir = LI->path(); |
358 | } |
359 | return Ver.size(); |
360 | } |
361 | |
362 | void toolchains::MinGW::findGccLibDir() { |
363 | llvm::SmallVector<llvm::SmallString<32>, 2> SubdirNames; |
364 | SubdirNames.emplace_back(getTriple().getArchName()); |
365 | SubdirNames[0] += "-w64-mingw32"; |
366 | SubdirNames.emplace_back("mingw32"); |
367 | if (SubdirName.empty()) |
368 | SubdirName = std::string(SubdirNames[0].str()); |
369 | // lib: Arch Linux, Ubuntu, Windows |
370 | // lib64: openSUSE Linux |
371 | for (StringRef CandidateLib : {"lib", "lib64"}) { |
372 | for (StringRef CandidateSysroot : SubdirNames) { |
373 | llvm::SmallString<1024> LibDir(Base); |
374 | llvm::sys::path::append(LibDir, CandidateLib, "gcc", CandidateSysroot); |
375 | if (findGccVersion(LibDir, GccLibDir, Ver, GccVer)) { |
376 | SubdirName = std::string(CandidateSysroot); |
377 | return; |
378 | } |
379 | } |
380 | } |
381 | } |
382 | |
383 | static llvm::ErrorOr<std::string> findGcc(const llvm::Triple &T) { |
384 | llvm::SmallVector<llvm::SmallString<32>, 2> Gccs; |
385 | Gccs.emplace_back(T.getArchName()); |
386 | Gccs[0] += "-w64-mingw32-gcc"; |
387 | Gccs.emplace_back("mingw32-gcc"); |
388 | // Please do not add "gcc" here |
389 | for (StringRef CandidateGcc : Gccs) |
390 | if (llvm::ErrorOr<std::string> GPPName = llvm::sys::findProgramByName(CandidateGcc)) |
391 | return GPPName; |
392 | return make_error_code(std::errc::no_such_file_or_directory); |
393 | } |
394 | |
395 | static llvm::ErrorOr<std::string> |
396 | findClangRelativeSysroot(const Driver &D, const llvm::Triple &T, |
397 | std::string &SubdirName) { |
398 | llvm::SmallVector<llvm::SmallString<32>, 2> Subdirs; |
399 | Subdirs.emplace_back(T.str()); |
400 | Subdirs.emplace_back(T.getArchName()); |
401 | Subdirs[1] += "-w64-mingw32"; |
402 | StringRef ClangRoot = llvm::sys::path::parent_path(D.getInstalledDir()); |
403 | StringRef Sep = llvm::sys::path::get_separator(); |
404 | for (StringRef CandidateSubdir : Subdirs) { |
405 | if (llvm::sys::fs::is_directory(ClangRoot + Sep + CandidateSubdir)) { |
406 | SubdirName = std::string(CandidateSubdir); |
407 | return (ClangRoot + Sep + CandidateSubdir).str(); |
408 | } |
409 | } |
410 | return make_error_code(std::errc::no_such_file_or_directory); |
411 | } |
412 | |
413 | toolchains::MinGW::MinGW(const Driver &D, const llvm::Triple &Triple, |
414 | const ArgList &Args) |
415 | : ToolChain(D, Triple, Args), CudaInstallation(D, Triple, Args), |
416 | RocmInstallation(D, Triple, Args) { |
417 | getProgramPaths().push_back(getDriver().getInstalledDir()); |
418 | |
419 | // The sequence for detecting a sysroot here should be kept in sync with |
420 | // the testTriple function below. |
421 | if (getDriver().SysRoot.size()) |
422 | Base = getDriver().SysRoot; |
423 | // Look for <clang-bin>/../<triplet>; if found, use <clang-bin>/.. as the |
424 | // base as it could still be a base for a gcc setup with libgcc. |
425 | else if (llvm::ErrorOr<std::string> TargetSubdir = |
426 | findClangRelativeSysroot(getDriver(), getTriple(), SubdirName)) |
427 | Base = std::string(llvm::sys::path::parent_path(TargetSubdir.get())); |
428 | else if (llvm::ErrorOr<std::string> GPPName = findGcc(getTriple())) |
429 | Base = std::string(llvm::sys::path::parent_path( |
430 | llvm::sys::path::parent_path(GPPName.get()))); |
431 | else |
432 | Base = std::string( |
433 | llvm::sys::path::parent_path(getDriver().getInstalledDir())); |
434 | |
435 | Base += llvm::sys::path::get_separator(); |
436 | findGccLibDir(); |
437 | // GccLibDir must precede Base/lib so that the |
438 | // correct crtbegin.o ,cetend.o would be found. |
439 | getFilePaths().push_back(GccLibDir); |
440 | getFilePaths().push_back( |
441 | (Base + SubdirName + llvm::sys::path::get_separator() + "lib").str()); |
442 | |
443 | // Gentoo |
444 | getFilePaths().push_back( |
445 | (Base + SubdirName + llvm::sys::path::get_separator() + "mingw/lib").str()); |
446 | |
447 | getFilePaths().push_back(Base + "lib"); |
448 | // openSUSE |
449 | getFilePaths().push_back(Base + SubdirName + "/sys-root/mingw/lib"); |
450 | |
451 | NativeLLVMSupport = |
452 | Args.getLastArgValue(options::OPT_fuse_ld_EQ, CLANG_DEFAULT_LINKER"ld") |
453 | .equals_insensitive("lld"); |
454 | } |
455 | |
456 | bool toolchains::MinGW::IsIntegratedAssemblerDefault() const { return true; } |
457 | |
458 | Tool *toolchains::MinGW::getTool(Action::ActionClass AC) const { |
459 | switch (AC) { |
460 | case Action::PreprocessJobClass: |
461 | if (!Preprocessor) |
462 | Preprocessor.reset(new tools::gcc::Preprocessor(*this)); |
463 | return Preprocessor.get(); |
464 | case Action::CompileJobClass: |
465 | if (!Compiler) |
466 | Compiler.reset(new tools::gcc::Compiler(*this)); |
467 | return Compiler.get(); |
468 | default: |
469 | return ToolChain::getTool(AC); |
470 | } |
471 | } |
472 | |
473 | Tool *toolchains::MinGW::buildAssembler() const { |
474 | return new tools::MinGW::Assembler(*this); |
475 | } |
476 | |
477 | Tool *toolchains::MinGW::buildLinker() const { |
478 | return new tools::MinGW::Linker(*this); |
479 | } |
480 | |
481 | bool toolchains::MinGW::HasNativeLLVMSupport() const { |
482 | return NativeLLVMSupport; |
483 | } |
484 | |
485 | bool toolchains::MinGW::IsUnwindTablesDefault(const ArgList &Args) const { |
486 | Arg *ExceptionArg = Args.getLastArg(options::OPT_fsjlj_exceptions, |
487 | options::OPT_fseh_exceptions, |
488 | options::OPT_fdwarf_exceptions); |
489 | if (ExceptionArg && |
490 | ExceptionArg->getOption().matches(options::OPT_fseh_exceptions)) |
491 | return true; |
492 | return getArch() == llvm::Triple::x86_64 || getArch() == llvm::Triple::arm || |
493 | getArch() == llvm::Triple::thumb || getArch() == llvm::Triple::aarch64; |
494 | } |
495 | |
496 | bool toolchains::MinGW::isPICDefault() const { |
497 | return getArch() == llvm::Triple::x86_64 || |
498 | getArch() == llvm::Triple::aarch64; |
499 | } |
500 | |
501 | bool toolchains::MinGW::isPIEDefault(const llvm::opt::ArgList &Args) const { |
502 | return false; |
503 | } |
504 | |
505 | bool toolchains::MinGW::isPICDefaultForced() const { return true; } |
506 | |
507 | llvm::ExceptionHandling |
508 | toolchains::MinGW::GetExceptionModel(const ArgList &Args) const { |
509 | if (getArch() == llvm::Triple::x86_64 || getArch() == llvm::Triple::aarch64 || |
510 | getArch() == llvm::Triple::arm || getArch() == llvm::Triple::thumb) |
511 | return llvm::ExceptionHandling::WinEH; |
512 | return llvm::ExceptionHandling::DwarfCFI; |
513 | } |
514 | |
515 | SanitizerMask toolchains::MinGW::getSupportedSanitizers() const { |
516 | SanitizerMask Res = ToolChain::getSupportedSanitizers(); |
517 | Res |= SanitizerKind::Address; |
518 | Res |= SanitizerKind::PointerCompare; |
519 | Res |= SanitizerKind::PointerSubtract; |
520 | Res |= SanitizerKind::Vptr; |
521 | return Res; |
522 | } |
523 | |
524 | void toolchains::MinGW::AddCudaIncludeArgs(const ArgList &DriverArgs, |
525 | ArgStringList &CC1Args) const { |
526 | CudaInstallation.AddCudaIncludeArgs(DriverArgs, CC1Args); |
527 | } |
528 | |
529 | void toolchains::MinGW::AddHIPIncludeArgs(const ArgList &DriverArgs, |
530 | ArgStringList &CC1Args) const { |
531 | RocmInstallation.AddHIPIncludeArgs(DriverArgs, CC1Args); |
532 | } |
533 | |
534 | void toolchains::MinGW::printVerboseInfo(raw_ostream &OS) const { |
535 | CudaInstallation.print(OS); |
536 | RocmInstallation.print(OS); |
537 | } |
538 | |
539 | // Include directories for various hosts: |
540 | |
541 | // Windows, mingw.org |
542 | // c:\mingw\lib\gcc\mingw32\4.8.1\include\c++ |
543 | // c:\mingw\lib\gcc\mingw32\4.8.1\include\c++\mingw32 |
544 | // c:\mingw\lib\gcc\mingw32\4.8.1\include\c++\backward |
545 | // c:\mingw\include |
546 | // c:\mingw\mingw32\include |
547 | |
548 | // Windows, mingw-w64 mingw-builds |
549 | // c:\mingw32\i686-w64-mingw32\include |
550 | // c:\mingw32\i686-w64-mingw32\include\c++ |
551 | // c:\mingw32\i686-w64-mingw32\include\c++\i686-w64-mingw32 |
552 | // c:\mingw32\i686-w64-mingw32\include\c++\backward |
553 | |
554 | // Windows, mingw-w64 msys2 |
555 | // c:\msys64\mingw32\include |
556 | // c:\msys64\mingw32\i686-w64-mingw32\include |
557 | // c:\msys64\mingw32\include\c++\4.9.2 |
558 | // c:\msys64\mingw32\include\c++\4.9.2\i686-w64-mingw32 |
559 | // c:\msys64\mingw32\include\c++\4.9.2\backward |
560 | |
561 | // openSUSE |
562 | // /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include/c++ |
563 | // /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include/c++/x86_64-w64-mingw32 |
564 | // /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include/c++/backward |
565 | // /usr/x86_64-w64-mingw32/sys-root/mingw/include |
566 | |
567 | // Arch Linux |
568 | // /usr/i686-w64-mingw32/include/c++/5.1.0 |
569 | // /usr/i686-w64-mingw32/include/c++/5.1.0/i686-w64-mingw32 |
570 | // /usr/i686-w64-mingw32/include/c++/5.1.0/backward |
571 | // /usr/i686-w64-mingw32/include |
572 | |
573 | // Ubuntu |
574 | // /usr/include/c++/4.8 |
575 | // /usr/include/c++/4.8/x86_64-w64-mingw32 |
576 | // /usr/include/c++/4.8/backward |
577 | // /usr/x86_64-w64-mingw32/include |
578 | |
579 | void toolchains::MinGW::AddClangSystemIncludeArgs(const ArgList &DriverArgs, |
580 | ArgStringList &CC1Args) const { |
581 | if (DriverArgs.hasArg(options::OPT_nostdinc)) |
582 | return; |
583 | |
584 | if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) { |
585 | SmallString<1024> P(getDriver().ResourceDir); |
586 | llvm::sys::path::append(P, "include"); |
587 | addSystemInclude(DriverArgs, CC1Args, P.str()); |
588 | } |
589 | |
590 | if (DriverArgs.hasArg(options::OPT_nostdlibinc)) |
591 | return; |
592 | |
593 | if (GetRuntimeLibType(DriverArgs) == ToolChain::RLT_Libgcc) { |
594 | // openSUSE |
595 | addSystemInclude(DriverArgs, CC1Args, |
596 | Base + SubdirName + "/sys-root/mingw/include"); |
597 | } |
598 | |
599 | addSystemInclude(DriverArgs, CC1Args, |
600 | Base + SubdirName + llvm::sys::path::get_separator() + |
601 | "include"); |
602 | |
603 | // Gentoo |
604 | addSystemInclude(DriverArgs, CC1Args, |
605 | Base + SubdirName + llvm::sys::path::get_separator() + "usr/include"); |
606 | |
607 | addSystemInclude(DriverArgs, CC1Args, Base + "include"); |
608 | } |
609 | |
610 | void toolchains::MinGW::AddClangCXXStdlibIncludeArgs( |
611 | const ArgList &DriverArgs, ArgStringList &CC1Args) const { |
612 | if (DriverArgs.hasArg(options::OPT_nostdlibinc) || |
613 | DriverArgs.hasArg(options::OPT_nostdincxx)) |
614 | return; |
615 | |
616 | StringRef Slash = llvm::sys::path::get_separator(); |
617 | |
618 | switch (GetCXXStdlibType(DriverArgs)) { |
619 | case ToolChain::CST_Libcxx: { |
620 | std::string TargetDir = (Base + "include" + Slash + getTripleString() + |
621 | Slash + "c++" + Slash + "v1") |
622 | .str(); |
623 | if (getDriver().getVFS().exists(TargetDir)) |
624 | addSystemInclude(DriverArgs, CC1Args, TargetDir); |
625 | addSystemInclude(DriverArgs, CC1Args, |
626 | Base + SubdirName + Slash + "include" + Slash + "c++" + |
627 | Slash + "v1"); |
628 | addSystemInclude(DriverArgs, CC1Args, |
629 | Base + "include" + Slash + "c++" + Slash + "v1"); |
630 | break; |
631 | } |
632 | |
633 | case ToolChain::CST_Libstdcxx: |
634 | llvm::SmallVector<llvm::SmallString<1024>, 7> CppIncludeBases; |
635 | CppIncludeBases.emplace_back(Base); |
636 | llvm::sys::path::append(CppIncludeBases[0], SubdirName, "include", "c++"); |
637 | CppIncludeBases.emplace_back(Base); |
638 | llvm::sys::path::append(CppIncludeBases[1], SubdirName, "include", "c++", |
639 | Ver); |
640 | CppIncludeBases.emplace_back(Base); |
641 | llvm::sys::path::append(CppIncludeBases[2], "include", "c++", Ver); |
642 | CppIncludeBases.emplace_back(GccLibDir); |
643 | llvm::sys::path::append(CppIncludeBases[3], "include", "c++"); |
644 | CppIncludeBases.emplace_back(GccLibDir); |
645 | llvm::sys::path::append(CppIncludeBases[4], "include", |
646 | "g++-v" + GccVer.Text); |
647 | CppIncludeBases.emplace_back(GccLibDir); |
648 | llvm::sys::path::append(CppIncludeBases[5], "include", |
649 | "g++-v" + GccVer.MajorStr + "." + GccVer.MinorStr); |
650 | CppIncludeBases.emplace_back(GccLibDir); |
651 | llvm::sys::path::append(CppIncludeBases[6], "include", |
652 | "g++-v" + GccVer.MajorStr); |
653 | for (auto &CppIncludeBase : CppIncludeBases) { |
654 | addSystemInclude(DriverArgs, CC1Args, CppIncludeBase); |
655 | CppIncludeBase += Slash; |
656 | addSystemInclude(DriverArgs, CC1Args, CppIncludeBase + SubdirName); |
657 | addSystemInclude(DriverArgs, CC1Args, CppIncludeBase + "backward"); |
658 | } |
659 | break; |
660 | } |
661 | } |
662 | |
663 | static bool testTriple(const Driver &D, const llvm::Triple &Triple, |
664 | const ArgList &Args) { |
665 | // If an explicit sysroot is set, that will be used and we shouldn't try to |
666 | // detect anything else. |
667 | std::string SubdirName; |
668 | if (D.SysRoot.size()) |
669 | return true; |
670 | if (llvm::ErrorOr<std::string> TargetSubdir = |
671 | findClangRelativeSysroot(D, Triple, SubdirName)) |
672 | return true; |
673 | if (llvm::ErrorOr<std::string> GPPName = findGcc(Triple)) |
674 | return true; |
675 | // If we neither found a colocated sysroot or a matching gcc executable, |
676 | // conclude that we can't know if this is the correct spelling of the triple. |
677 | return false; |
678 | } |
679 | |
680 | static llvm::Triple adjustTriple(const Driver &D, const llvm::Triple &Triple, |
681 | const ArgList &Args) { |
682 | // First test if the original triple can find a sysroot with the triple |
683 | // name. |
684 | if (testTriple(D, Triple, Args)) |
685 | return Triple; |
686 | llvm::SmallVector<llvm::StringRef, 3> Archs; |
687 | // If not, test a couple other possible arch names that might be what was |
688 | // intended. |
689 | if (Triple.getArch() == llvm::Triple::x86) { |
690 | Archs.emplace_back("i386"); |
691 | Archs.emplace_back("i586"); |
692 | Archs.emplace_back("i686"); |
693 | } else if (Triple.getArch() == llvm::Triple::arm || |
694 | Triple.getArch() == llvm::Triple::thumb) { |
695 | Archs.emplace_back("armv7"); |
696 | } |
697 | for (auto A : Archs) { |
698 | llvm::Triple TestTriple(Triple); |
699 | TestTriple.setArchName(A); |
700 | if (testTriple(D, TestTriple, Args)) |
701 | return TestTriple; |
702 | } |
703 | // If none was found, just proceed with the original value. |
704 | return Triple; |
705 | } |
706 | |
707 | void toolchains::MinGW::fixTripleArch(const Driver &D, llvm::Triple &Triple, |
708 | const ArgList &Args) { |
709 | if (Triple.getArch() == llvm::Triple::x86 || |
710 | Triple.getArch() == llvm::Triple::arm || |
711 | Triple.getArch() == llvm::Triple::thumb) |
712 | Triple = adjustTriple(D, Triple, Args); |
713 | } |