/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Driver/ToolChains/MinGW.cpp
Line | Count | Source (jump to first uncovered line) |
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 "InputInfo.h" |
11 | | #include "CommonArgs.h" |
12 | | #include "clang/Config/config.h" |
13 | | #include "clang/Driver/Compilation.h" |
14 | | #include "clang/Driver/Driver.h" |
15 | | #include "clang/Driver/DriverDiagnostic.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 | 1 | const char *LinkingOutput) const { |
35 | 1 | claimNoWarnArgs(Args); |
36 | 1 | ArgStringList CmdArgs; |
37 | | |
38 | 1 | if (getToolChain().getArch() == llvm::Triple::x86) { |
39 | 1 | CmdArgs.push_back("--32"); |
40 | 0 | } else if (getToolChain().getArch() == llvm::Triple::x86_64) { |
41 | 0 | CmdArgs.push_back("--64"); |
42 | 0 | } |
43 | | |
44 | 1 | Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler); |
45 | | |
46 | 1 | CmdArgs.push_back("-o"); |
47 | 1 | CmdArgs.push_back(Output.getFilename()); |
48 | | |
49 | 1 | for (const auto &II : Inputs) |
50 | 1 | CmdArgs.push_back(II.getFilename()); |
51 | | |
52 | 1 | const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as")); |
53 | 1 | C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(), |
54 | 1 | Exec, CmdArgs, Inputs, Output)); |
55 | | |
56 | 1 | if (Args.hasArg(options::OPT_gsplit_dwarf)) |
57 | 0 | SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output, |
58 | 0 | SplitDebugName(JA, Args, Inputs[0], Output)); |
59 | 1 | } |
60 | | |
61 | | void tools::MinGW::Linker::AddLibGCC(const ArgList &Args, |
62 | 106 | ArgStringList &CmdArgs) const { |
63 | 106 | if (Args.hasArg(options::OPT_mthreads)) |
64 | 0 | CmdArgs.push_back("-lmingwthrd"); |
65 | 106 | CmdArgs.push_back("-lmingw32"); |
66 | | |
67 | | // Make use of compiler-rt if --rtlib option is used |
68 | 106 | ToolChain::RuntimeLibType RLT = getToolChain().GetRuntimeLibType(Args); |
69 | 106 | if (RLT == ToolChain::RLT_Libgcc) { |
70 | 100 | bool Static = Args.hasArg(options::OPT_static_libgcc) || |
71 | 92 | Args.hasArg(options::OPT_static); |
72 | 100 | bool Shared = Args.hasArg(options::OPT_shared); |
73 | 100 | bool CXX = getToolChain().getDriver().CCCIsCXX(); |
74 | | |
75 | 100 | if (Static || (88 !CXX88 && !Shared84 )) { |
76 | 94 | CmdArgs.push_back("-lgcc"); |
77 | 94 | CmdArgs.push_back("-lgcc_eh"); |
78 | 6 | } else { |
79 | 6 | CmdArgs.push_back("-lgcc_s"); |
80 | 6 | CmdArgs.push_back("-lgcc"); |
81 | 6 | } |
82 | 6 | } else { |
83 | 6 | AddRunTimeLibs(getToolChain(), getToolChain().getDriver(), CmdArgs, Args); |
84 | 6 | } |
85 | | |
86 | 106 | CmdArgs.push_back("-lmoldname"); |
87 | 106 | CmdArgs.push_back("-lmingwex"); |
88 | 106 | for (auto Lib : Args.getAllArgValues(options::OPT_l)) |
89 | 8 | if (StringRef(Lib).startswith("msvcr") || StringRef(Lib).startswith("ucrt")6 ) |
90 | 6 | return; |
91 | 100 | CmdArgs.push_back("-lmsvcrt"); |
92 | 100 | } |
93 | | |
94 | | void tools::MinGW::Linker::ConstructJob(Compilation &C, const JobAction &JA, |
95 | | const InputInfo &Output, |
96 | | const InputInfoList &Inputs, |
97 | | const ArgList &Args, |
98 | 58 | const char *LinkingOutput) const { |
99 | 58 | const ToolChain &TC = getToolChain(); |
100 | 58 | const Driver &D = TC.getDriver(); |
101 | 58 | const SanitizerArgs &Sanitize = TC.getSanitizerArgs(); |
102 | | |
103 | 58 | ArgStringList CmdArgs; |
104 | | |
105 | | // Silence warning for "clang -g foo.o -o foo" |
106 | 58 | Args.ClaimAllArgs(options::OPT_g_Group); |
107 | | // and "clang -emit-llvm foo.o -o foo" |
108 | 58 | Args.ClaimAllArgs(options::OPT_emit_llvm); |
109 | | // and for "clang -w foo.o -o foo". Other warning options are already |
110 | | // handled somewhere else. |
111 | 58 | Args.ClaimAllArgs(options::OPT_w); |
112 | | |
113 | 58 | if (!D.SysRoot.empty()) |
114 | 3 | CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot)); |
115 | | |
116 | 58 | if (Args.hasArg(options::OPT_s)) |
117 | 0 | CmdArgs.push_back("-s"); |
118 | | |
119 | 58 | CmdArgs.push_back("-m"); |
120 | 58 | switch (TC.getArch()) { |
121 | 34 | case llvm::Triple::x86: |
122 | 34 | CmdArgs.push_back("i386pe"); |
123 | 34 | break; |
124 | 24 | case llvm::Triple::x86_64: |
125 | 24 | CmdArgs.push_back("i386pep"); |
126 | 24 | break; |
127 | 0 | case llvm::Triple::arm: |
128 | 0 | case llvm::Triple::thumb: |
129 | | // FIXME: this is incorrect for WinCE |
130 | 0 | CmdArgs.push_back("thumb2pe"); |
131 | 0 | break; |
132 | 0 | case llvm::Triple::aarch64: |
133 | 0 | CmdArgs.push_back("arm64pe"); |
134 | 0 | break; |
135 | 0 | default: |
136 | 0 | llvm_unreachable("Unsupported target architecture."); |
137 | 58 | } |
138 | | |
139 | 58 | if (Args.hasArg(options::OPT_mwindows)) { |
140 | 0 | CmdArgs.push_back("--subsystem"); |
141 | 0 | CmdArgs.push_back("windows"); |
142 | 58 | } else if (Args.hasArg(options::OPT_mconsole)) { |
143 | 0 | CmdArgs.push_back("--subsystem"); |
144 | 0 | CmdArgs.push_back("console"); |
145 | 0 | } |
146 | | |
147 | 58 | if (Args.hasArg(options::OPT_mdll)) |
148 | 0 | CmdArgs.push_back("--dll"); |
149 | 58 | else if (Args.hasArg(options::OPT_shared)) |
150 | 6 | CmdArgs.push_back("--shared"); |
151 | 58 | if (Args.hasArg(options::OPT_static)) |
152 | 4 | CmdArgs.push_back("-Bstatic"); |
153 | 54 | else |
154 | 54 | CmdArgs.push_back("-Bdynamic"); |
155 | 58 | if (Args.hasArg(options::OPT_mdll) || Args.hasArg(options::OPT_shared)) { |
156 | 6 | CmdArgs.push_back("-e"); |
157 | 6 | if (TC.getArch() == llvm::Triple::x86) |
158 | 6 | CmdArgs.push_back("_DllMainCRTStartup@12"); |
159 | 0 | else |
160 | 0 | CmdArgs.push_back("DllMainCRTStartup"); |
161 | 6 | CmdArgs.push_back("--enable-auto-image-base"); |
162 | 6 | } |
163 | | |
164 | 58 | CmdArgs.push_back("-o"); |
165 | 58 | const char *OutputFile = Output.getFilename(); |
166 | | // GCC implicitly adds an .exe extension if it is given an output file name |
167 | | // that lacks an extension. |
168 | | // GCC used to do this only when the compiler itself runs on windows, but |
169 | | // since GCC 8 it does the same when cross compiling as well. |
170 | 58 | if (!llvm::sys::path::has_extension(OutputFile)) { |
171 | 1 | CmdArgs.push_back(Args.MakeArgString(Twine(OutputFile) + ".exe")); |
172 | 1 | OutputFile = CmdArgs.back(); |
173 | 1 | } else |
174 | 57 | CmdArgs.push_back(OutputFile); |
175 | | |
176 | 58 | Args.AddAllArgs(CmdArgs, options::OPT_e); |
177 | | // FIXME: add -N, -n flags |
178 | 58 | Args.AddLastArg(CmdArgs, options::OPT_r); |
179 | 58 | Args.AddLastArg(CmdArgs, options::OPT_s); |
180 | 58 | Args.AddLastArg(CmdArgs, options::OPT_t); |
181 | 58 | Args.AddAllArgs(CmdArgs, options::OPT_u_Group); |
182 | 58 | Args.AddLastArg(CmdArgs, options::OPT_Z_Flag); |
183 | | |
184 | 58 | if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) { |
185 | 55 | if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_mdll)49 ) { |
186 | 6 | CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("dllcrt2.o"))); |
187 | 49 | } else { |
188 | 49 | if (Args.hasArg(options::OPT_municode)) |
189 | 0 | CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crt2u.o"))); |
190 | 49 | else |
191 | 49 | CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crt2.o"))); |
192 | 49 | } |
193 | 55 | if (Args.hasArg(options::OPT_pg)) |
194 | 0 | CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("gcrt2.o"))); |
195 | 55 | CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crtbegin.o"))); |
196 | 55 | } |
197 | | |
198 | 58 | Args.AddAllArgs(CmdArgs, options::OPT_L); |
199 | 58 | TC.AddFilePathLibArgs(Args, CmdArgs); |
200 | | |
201 | | // Add the compiler-rt library directories if they exist to help |
202 | | // the linker find the various sanitizer, builtin, and profiling runtimes. |
203 | 0 | for (const auto &LibPath : TC.getLibraryPaths()) { |
204 | 0 | if (TC.getVFS().exists(LibPath)) |
205 | 0 | CmdArgs.push_back(Args.MakeArgString("-L" + LibPath)); |
206 | 0 | } |
207 | 58 | auto CRTPath = TC.getCompilerRTPath(); |
208 | 58 | if (TC.getVFS().exists(CRTPath)) |
209 | 0 | CmdArgs.push_back(Args.MakeArgString("-L" + CRTPath)); |
210 | | |
211 | 58 | AddLinkerInputs(TC, Inputs, Args, CmdArgs, JA); |
212 | | |
213 | | // TODO: Add profile stuff here |
214 | | |
215 | 58 | if (TC.ShouldLinkCXXStdlib(Args)) { |
216 | 6 | bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) && |
217 | 0 | !Args.hasArg(options::OPT_static); |
218 | 6 | if (OnlyLibstdcxxStatic) |
219 | 0 | CmdArgs.push_back("-Bstatic"); |
220 | 6 | TC.AddCXXStdlibLibArgs(Args, CmdArgs); |
221 | 6 | if (OnlyLibstdcxxStatic) |
222 | 0 | CmdArgs.push_back("-Bdynamic"); |
223 | 6 | } |
224 | | |
225 | 58 | bool HasWindowsApp = false; |
226 | 4 | for (auto Lib : Args.getAllArgValues(options::OPT_l)) { |
227 | 4 | if (Lib == "windowsapp") { |
228 | 1 | HasWindowsApp = true; |
229 | 1 | break; |
230 | 1 | } |
231 | 4 | } |
232 | | |
233 | 58 | if (!Args.hasArg(options::OPT_nostdlib)) { |
234 | 55 | if (!Args.hasArg(options::OPT_nodefaultlibs)) { |
235 | 55 | if (Args.hasArg(options::OPT_static)) |
236 | 4 | CmdArgs.push_back("--start-group"); |
237 | | |
238 | 55 | if (Args.hasArg(options::OPT_fstack_protector) || |
239 | 55 | Args.hasArg(options::OPT_fstack_protector_strong) || |
240 | 55 | Args.hasArg(options::OPT_fstack_protector_all)) { |
241 | 0 | CmdArgs.push_back("-lssp_nonshared"); |
242 | 0 | CmdArgs.push_back("-lssp"); |
243 | 0 | } |
244 | | |
245 | 55 | if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ, |
246 | 4 | options::OPT_fno_openmp, false)) { |
247 | 4 | switch (TC.getDriver().getOpenMPRuntime(Args)) { |
248 | 2 | case Driver::OMPRT_OMP: |
249 | 2 | CmdArgs.push_back("-lomp"); |
250 | 2 | break; |
251 | 1 | case Driver::OMPRT_IOMP5: |
252 | 1 | CmdArgs.push_back("-liomp5md"); |
253 | 1 | break; |
254 | 1 | case Driver::OMPRT_GOMP: |
255 | 1 | CmdArgs.push_back("-lgomp"); |
256 | 1 | break; |
257 | 0 | case Driver::OMPRT_Unknown: |
258 | | // Already diagnosed. |
259 | 0 | break; |
260 | 55 | } |
261 | 55 | } |
262 | | |
263 | 55 | AddLibGCC(Args, CmdArgs); |
264 | | |
265 | 55 | if (Args.hasArg(options::OPT_pg)) |
266 | 0 | CmdArgs.push_back("-lgmon"); |
267 | | |
268 | 55 | if (Args.hasArg(options::OPT_pthread)) |
269 | 0 | CmdArgs.push_back("-lpthread"); |
270 | | |
271 | 55 | if (Sanitize.needsAsanRt()) { |
272 | | // MinGW always links against a shared MSVCRT. |
273 | 2 | CmdArgs.push_back(TC.getCompilerRTArgString(Args, "asan_dynamic", |
274 | 2 | ToolChain::FT_Shared)); |
275 | 2 | CmdArgs.push_back( |
276 | 2 | TC.getCompilerRTArgString(Args, "asan_dynamic_runtime_thunk")); |
277 | 2 | CmdArgs.push_back("--require-defined"); |
278 | 2 | CmdArgs.push_back(TC.getArch() == llvm::Triple::x86 |
279 | 1 | ? "___asan_seh_interceptor" |
280 | 1 | : "__asan_seh_interceptor"); |
281 | | // Make sure the linker consider all object files from the dynamic |
282 | | // runtime thunk. |
283 | 2 | CmdArgs.push_back("--whole-archive"); |
284 | 2 | CmdArgs.push_back( |
285 | 2 | TC.getCompilerRTArgString(Args, "asan_dynamic_runtime_thunk")); |
286 | 2 | CmdArgs.push_back("--no-whole-archive"); |
287 | 2 | } |
288 | | |
289 | 55 | TC.addProfileRTLibs(Args, CmdArgs); |
290 | | |
291 | 55 | if (!HasWindowsApp) { |
292 | | // Add system libraries. If linking to libwindowsapp.a, that import |
293 | | // library replaces all these and we shouldn't accidentally try to |
294 | | // link to the normal desktop mode dlls. |
295 | 54 | if (Args.hasArg(options::OPT_mwindows)) { |
296 | 0 | CmdArgs.push_back("-lgdi32"); |
297 | 0 | CmdArgs.push_back("-lcomdlg32"); |
298 | 0 | } |
299 | 54 | CmdArgs.push_back("-ladvapi32"); |
300 | 54 | CmdArgs.push_back("-lshell32"); |
301 | 54 | CmdArgs.push_back("-luser32"); |
302 | 54 | CmdArgs.push_back("-lkernel32"); |
303 | 54 | } |
304 | | |
305 | 55 | if (Args.hasArg(options::OPT_static)) { |
306 | 4 | CmdArgs.push_back("--end-group"); |
307 | 51 | } else { |
308 | 51 | AddLibGCC(Args, CmdArgs); |
309 | 51 | if (!HasWindowsApp) |
310 | 50 | CmdArgs.push_back("-lkernel32"); |
311 | 51 | } |
312 | 55 | } |
313 | | |
314 | 55 | if (!Args.hasArg(options::OPT_nostartfiles)) { |
315 | | // Add crtfastmath.o if available and fast math is enabled. |
316 | 55 | TC.addFastMathRuntimeIfAvailable(Args, CmdArgs); |
317 | | |
318 | 55 | CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crtend.o"))); |
319 | 55 | } |
320 | 55 | } |
321 | 58 | const char *Exec = Args.MakeArgString(TC.GetLinkerPath()); |
322 | 58 | C.addCommand(std::make_unique<Command>(JA, *this, |
323 | 58 | ResponseFileSupport::AtFileUTF8(), |
324 | 58 | Exec, CmdArgs, Inputs, Output)); |
325 | 58 | } |
326 | | |
327 | | // Simplified from Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple. |
328 | | static bool findGccVersion(StringRef LibDir, std::string &GccLibDir, |
329 | 372 | std::string &Ver) { |
330 | 372 | auto Version = toolchains::Generic_GCC::GCCVersion::Parse("0.0.0"); |
331 | 372 | std::error_code EC; |
332 | 381 | for (llvm::sys::fs::directory_iterator LI(LibDir, EC), LE; !EC && LI != LE18 ; |
333 | 9 | LI = LI.increment(EC)) { |
334 | 9 | StringRef VersionText = llvm::sys::path::filename(LI->path()); |
335 | 9 | auto CandidateVersion = |
336 | 9 | toolchains::Generic_GCC::GCCVersion::Parse(VersionText); |
337 | 9 | if (CandidateVersion.Major == -1) |
338 | 0 | continue; |
339 | 9 | if (CandidateVersion <= Version) |
340 | 0 | continue; |
341 | 9 | Ver = std::string(VersionText); |
342 | 9 | GccLibDir = LI->path(); |
343 | 9 | } |
344 | 372 | return Ver.size(); |
345 | 372 | } |
346 | | |
347 | 99 | void toolchains::MinGW::findGccLibDir() { |
348 | 99 | llvm::SmallVector<llvm::SmallString<32>, 2> Archs; |
349 | 99 | Archs.emplace_back(getTriple().getArchName()); |
350 | 99 | Archs[0] += "-w64-mingw32"; |
351 | 99 | Archs.emplace_back("mingw32"); |
352 | 99 | if (Arch.empty()) |
353 | 97 | Arch = std::string(Archs[0].str()); |
354 | | // lib: Arch Linux, Ubuntu, Windows |
355 | | // lib64: openSUSE Linux |
356 | 190 | for (StringRef CandidateLib : {"lib", "lib64"}) { |
357 | 372 | for (StringRef CandidateArch : Archs) { |
358 | 372 | llvm::SmallString<1024> LibDir(Base); |
359 | 372 | llvm::sys::path::append(LibDir, CandidateLib, "gcc", CandidateArch); |
360 | 372 | if (findGccVersion(LibDir, GccLibDir, Ver)) { |
361 | 9 | Arch = std::string(CandidateArch); |
362 | 9 | return; |
363 | 9 | } |
364 | 372 | } |
365 | 190 | } |
366 | 99 | } |
367 | | |
368 | 85 | llvm::ErrorOr<std::string> toolchains::MinGW::findGcc() { |
369 | 85 | llvm::SmallVector<llvm::SmallString<32>, 2> Gccs; |
370 | 85 | Gccs.emplace_back(getTriple().getArchName()); |
371 | 85 | Gccs[0] += "-w64-mingw32-gcc"; |
372 | 85 | Gccs.emplace_back("mingw32-gcc"); |
373 | | // Please do not add "gcc" here |
374 | 85 | for (StringRef CandidateGcc : Gccs) |
375 | 169 | if (llvm::ErrorOr<std::string> GPPName = llvm::sys::findProgramByName(CandidateGcc)) |
376 | 1 | return GPPName; |
377 | 84 | return make_error_code(std::errc::no_such_file_or_directory); |
378 | 85 | } |
379 | | |
380 | 87 | llvm::ErrorOr<std::string> toolchains::MinGW::findClangRelativeSysroot() { |
381 | 87 | llvm::SmallVector<llvm::SmallString<32>, 2> Subdirs; |
382 | 87 | Subdirs.emplace_back(getTriple().str()); |
383 | 87 | Subdirs.emplace_back(getTriple().getArchName()); |
384 | 87 | Subdirs[1] += "-w64-mingw32"; |
385 | 87 | StringRef ClangRoot = |
386 | 87 | llvm::sys::path::parent_path(getDriver().getInstalledDir()); |
387 | 87 | StringRef Sep = llvm::sys::path::get_separator(); |
388 | 174 | for (StringRef CandidateSubdir : Subdirs) { |
389 | 174 | if (llvm::sys::fs::is_directory(ClangRoot + Sep + CandidateSubdir)) { |
390 | 2 | Arch = std::string(CandidateSubdir); |
391 | 2 | return (ClangRoot + Sep + CandidateSubdir).str(); |
392 | 2 | } |
393 | 174 | } |
394 | 85 | return make_error_code(std::errc::no_such_file_or_directory); |
395 | 87 | } |
396 | | |
397 | | toolchains::MinGW::MinGW(const Driver &D, const llvm::Triple &Triple, |
398 | | const ArgList &Args) |
399 | | : ToolChain(D, Triple, Args), CudaInstallation(D, Triple, Args), |
400 | 99 | RocmInstallation(D, Triple, Args) { |
401 | 99 | getProgramPaths().push_back(getDriver().getInstalledDir()); |
402 | | |
403 | 99 | if (getDriver().SysRoot.size()) |
404 | 12 | Base = getDriver().SysRoot; |
405 | | // Look for <clang-bin>/../<triplet>; if found, use <clang-bin>/.. as the |
406 | | // base as it could still be a base for a gcc setup with libgcc. |
407 | 87 | else if (llvm::ErrorOr<std::string> TargetSubdir = findClangRelativeSysroot()) |
408 | 2 | Base = std::string(llvm::sys::path::parent_path(TargetSubdir.get())); |
409 | 85 | else if (llvm::ErrorOr<std::string> GPPName = findGcc()) |
410 | 1 | Base = std::string(llvm::sys::path::parent_path( |
411 | 1 | llvm::sys::path::parent_path(GPPName.get()))); |
412 | 84 | else |
413 | 84 | Base = std::string( |
414 | 84 | llvm::sys::path::parent_path(getDriver().getInstalledDir())); |
415 | | |
416 | 99 | Base += llvm::sys::path::get_separator(); |
417 | 99 | findGccLibDir(); |
418 | | // GccLibDir must precede Base/lib so that the |
419 | | // correct crtbegin.o ,cetend.o would be found. |
420 | 99 | getFilePaths().push_back(GccLibDir); |
421 | 99 | getFilePaths().push_back( |
422 | 99 | (Base + Arch + llvm::sys::path::get_separator() + "lib").str()); |
423 | 99 | getFilePaths().push_back(Base + "lib"); |
424 | | // openSUSE |
425 | 99 | getFilePaths().push_back(Base + Arch + "/sys-root/mingw/lib"); |
426 | | |
427 | 99 | NativeLLVMSupport = |
428 | 99 | Args.getLastArgValue(options::OPT_fuse_ld_EQ, CLANG_DEFAULT_LINKER) |
429 | 99 | .equals_lower("lld"); |
430 | 99 | } |
431 | | |
432 | 616 | bool toolchains::MinGW::IsIntegratedAssemblerDefault() const { return true; } |
433 | | |
434 | 59 | Tool *toolchains::MinGW::getTool(Action::ActionClass AC) const { |
435 | 59 | switch (AC) { |
436 | 0 | case Action::PreprocessJobClass: |
437 | 0 | if (!Preprocessor) |
438 | 0 | Preprocessor.reset(new tools::gcc::Preprocessor(*this)); |
439 | 0 | return Preprocessor.get(); |
440 | 0 | case Action::CompileJobClass: |
441 | 0 | if (!Compiler) |
442 | 0 | Compiler.reset(new tools::gcc::Compiler(*this)); |
443 | 0 | return Compiler.get(); |
444 | 59 | default: |
445 | 59 | return ToolChain::getTool(AC); |
446 | 59 | } |
447 | 59 | } |
448 | | |
449 | 1 | Tool *toolchains::MinGW::buildAssembler() const { |
450 | 1 | return new tools::MinGW::Assembler(*this); |
451 | 1 | } |
452 | | |
453 | 58 | Tool *toolchains::MinGW::buildLinker() const { |
454 | 58 | return new tools::MinGW::Linker(*this); |
455 | 58 | } |
456 | | |
457 | 62 | bool toolchains::MinGW::HasNativeLLVMSupport() const { |
458 | 62 | return NativeLLVMSupport; |
459 | 62 | } |
460 | | |
461 | 99 | bool toolchains::MinGW::IsUnwindTablesDefault(const ArgList &Args) const { |
462 | 99 | Arg *ExceptionArg = Args.getLastArg(options::OPT_fsjlj_exceptions, |
463 | 99 | options::OPT_fseh_exceptions, |
464 | 99 | options::OPT_fdwarf_exceptions); |
465 | 99 | if (ExceptionArg && |
466 | 7 | ExceptionArg->getOption().matches(options::OPT_fseh_exceptions)) |
467 | 1 | return true; |
468 | 98 | return getArch() == llvm::Triple::x86_64 || |
469 | 54 | getArch() == llvm::Triple::aarch64; |
470 | 98 | } |
471 | | |
472 | 99 | bool toolchains::MinGW::isPICDefault() const { |
473 | 99 | return getArch() == llvm::Triple::x86_64; |
474 | 99 | } |
475 | | |
476 | 99 | bool toolchains::MinGW::isPIEDefault() const { return false; } |
477 | | |
478 | 91 | bool toolchains::MinGW::isPICDefaultForced() const { |
479 | 91 | return getArch() == llvm::Triple::x86_64; |
480 | 91 | } |
481 | | |
482 | | llvm::ExceptionHandling |
483 | 92 | toolchains::MinGW::GetExceptionModel(const ArgList &Args) const { |
484 | 92 | if (getArch() == llvm::Triple::x86_64 || getArch() == llvm::Triple::aarch6452 ) |
485 | 41 | return llvm::ExceptionHandling::WinEH; |
486 | 51 | return llvm::ExceptionHandling::DwarfCFI; |
487 | 51 | } |
488 | | |
489 | 99 | SanitizerMask toolchains::MinGW::getSupportedSanitizers() const { |
490 | 99 | SanitizerMask Res = ToolChain::getSupportedSanitizers(); |
491 | 99 | Res |= SanitizerKind::Address; |
492 | 99 | Res |= SanitizerKind::PointerCompare; |
493 | 99 | Res |= SanitizerKind::PointerSubtract; |
494 | 99 | Res |= SanitizerKind::Vptr; |
495 | 99 | return Res; |
496 | 99 | } |
497 | | |
498 | | void toolchains::MinGW::AddCudaIncludeArgs(const ArgList &DriverArgs, |
499 | 0 | ArgStringList &CC1Args) const { |
500 | 0 | CudaInstallation.AddCudaIncludeArgs(DriverArgs, CC1Args); |
501 | 0 | } |
502 | | |
503 | | void toolchains::MinGW::AddHIPIncludeArgs(const ArgList &DriverArgs, |
504 | 0 | ArgStringList &CC1Args) const { |
505 | 0 | RocmInstallation.AddHIPIncludeArgs(DriverArgs, CC1Args); |
506 | 0 | } |
507 | | |
508 | 18 | void toolchains::MinGW::printVerboseInfo(raw_ostream &OS) const { |
509 | 18 | CudaInstallation.print(OS); |
510 | 18 | RocmInstallation.print(OS); |
511 | 18 | } |
512 | | |
513 | | // Include directories for various hosts: |
514 | | |
515 | | // Windows, mingw.org |
516 | | // c:\mingw\lib\gcc\mingw32\4.8.1\include\c++ |
517 | | // c:\mingw\lib\gcc\mingw32\4.8.1\include\c++\mingw32 |
518 | | // c:\mingw\lib\gcc\mingw32\4.8.1\include\c++\backward |
519 | | // c:\mingw\include |
520 | | // c:\mingw\mingw32\include |
521 | | |
522 | | // Windows, mingw-w64 mingw-builds |
523 | | // c:\mingw32\i686-w64-mingw32\include |
524 | | // c:\mingw32\i686-w64-mingw32\include\c++ |
525 | | // c:\mingw32\i686-w64-mingw32\include\c++\i686-w64-mingw32 |
526 | | // c:\mingw32\i686-w64-mingw32\include\c++\backward |
527 | | |
528 | | // Windows, mingw-w64 msys2 |
529 | | // c:\msys64\mingw32\include |
530 | | // c:\msys64\mingw32\i686-w64-mingw32\include |
531 | | // c:\msys64\mingw32\include\c++\4.9.2 |
532 | | // c:\msys64\mingw32\include\c++\4.9.2\i686-w64-mingw32 |
533 | | // c:\msys64\mingw32\include\c++\4.9.2\backward |
534 | | |
535 | | // openSUSE |
536 | | // /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include/c++ |
537 | | // /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include/c++/x86_64-w64-mingw32 |
538 | | // /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include/c++/backward |
539 | | // /usr/x86_64-w64-mingw32/sys-root/mingw/include |
540 | | |
541 | | // Arch Linux |
542 | | // /usr/i686-w64-mingw32/include/c++/5.1.0 |
543 | | // /usr/i686-w64-mingw32/include/c++/5.1.0/i686-w64-mingw32 |
544 | | // /usr/i686-w64-mingw32/include/c++/5.1.0/backward |
545 | | // /usr/i686-w64-mingw32/include |
546 | | |
547 | | // Ubuntu |
548 | | // /usr/include/c++/4.8 |
549 | | // /usr/include/c++/4.8/x86_64-w64-mingw32 |
550 | | // /usr/include/c++/4.8/backward |
551 | | // /usr/x86_64-w64-mingw32/include |
552 | | |
553 | | void toolchains::MinGW::AddClangSystemIncludeArgs(const ArgList &DriverArgs, |
554 | 99 | ArgStringList &CC1Args) const { |
555 | 99 | if (DriverArgs.hasArg(options::OPT_nostdinc)) |
556 | 0 | return; |
557 | | |
558 | 99 | if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) { |
559 | 99 | SmallString<1024> P(getDriver().ResourceDir); |
560 | 99 | llvm::sys::path::append(P, "include"); |
561 | 99 | addSystemInclude(DriverArgs, CC1Args, P.str()); |
562 | 99 | } |
563 | | |
564 | 99 | if (DriverArgs.hasArg(options::OPT_nostdlibinc)) |
565 | 0 | return; |
566 | | |
567 | 99 | if (GetRuntimeLibType(DriverArgs) == ToolChain::RLT_Libgcc) { |
568 | | // openSUSE |
569 | 95 | addSystemInclude(DriverArgs, CC1Args, |
570 | 95 | Base + Arch + "/sys-root/mingw/include"); |
571 | 95 | } |
572 | | |
573 | 99 | addSystemInclude(DriverArgs, CC1Args, |
574 | 99 | Base + Arch + llvm::sys::path::get_separator() + "include"); |
575 | 99 | addSystemInclude(DriverArgs, CC1Args, Base + "include"); |
576 | 99 | } |
577 | | |
578 | | void toolchains::MinGW::AddClangCXXStdlibIncludeArgs( |
579 | 45 | const ArgList &DriverArgs, ArgStringList &CC1Args) const { |
580 | 45 | if (DriverArgs.hasArg(options::OPT_nostdlibinc) || |
581 | 45 | DriverArgs.hasArg(options::OPT_nostdincxx)) |
582 | 0 | return; |
583 | | |
584 | 45 | StringRef Slash = llvm::sys::path::get_separator(); |
585 | | |
586 | 45 | switch (GetCXXStdlibType(DriverArgs)) { |
587 | 1 | case ToolChain::CST_Libcxx: |
588 | 1 | addSystemInclude(DriverArgs, CC1Args, Base + Arch + Slash + "include" + |
589 | 1 | Slash + "c++" + Slash + "v1"); |
590 | 1 | addSystemInclude(DriverArgs, CC1Args, |
591 | 1 | Base + "include" + Slash + "c++" + Slash + "v1"); |
592 | 1 | break; |
593 | | |
594 | 44 | case ToolChain::CST_Libstdcxx: |
595 | 44 | llvm::SmallVector<llvm::SmallString<1024>, 4> CppIncludeBases; |
596 | 44 | CppIncludeBases.emplace_back(Base); |
597 | 44 | llvm::sys::path::append(CppIncludeBases[0], Arch, "include", "c++"); |
598 | 44 | CppIncludeBases.emplace_back(Base); |
599 | 44 | llvm::sys::path::append(CppIncludeBases[1], Arch, "include", "c++", Ver); |
600 | 44 | CppIncludeBases.emplace_back(Base); |
601 | 44 | llvm::sys::path::append(CppIncludeBases[2], "include", "c++", Ver); |
602 | 44 | CppIncludeBases.emplace_back(GccLibDir); |
603 | 44 | llvm::sys::path::append(CppIncludeBases[3], "include", "c++"); |
604 | 176 | for (auto &CppIncludeBase : CppIncludeBases) { |
605 | 176 | addSystemInclude(DriverArgs, CC1Args, CppIncludeBase); |
606 | 176 | CppIncludeBase += Slash; |
607 | 176 | addSystemInclude(DriverArgs, CC1Args, CppIncludeBase + Arch); |
608 | 176 | addSystemInclude(DriverArgs, CC1Args, CppIncludeBase + "backward"); |
609 | 176 | } |
610 | 44 | break; |
611 | 45 | } |
612 | 45 | } |