Coverage Report

Created: 2022-01-22 13:19

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