Clang Project

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