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 23 using namespace clang::diag; 24 using namespace clang::driver; 25 using namespace clang; 26 using namespace llvm::opt; 27 28 /// MinGW Tools 29 void 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(std::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 59 void 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 92 void 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("--require-defined"); 256 CmdArgs.push_back(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("--whole-archive"); 262 CmdArgs.push_back( 263 TC.getCompilerRTArgString(Args, "asan_dynamic_runtime_thunk")); 264 CmdArgs.push_back("--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(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs)); 298 } 299 300 // Simplified from Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple. 301 static bool findGccVersion(StringRef LibDir, std::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 320 void 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 341 llvm::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 353 llvm::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 370 toolchains::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 403 bool toolchains::MinGW::IsIntegratedAssemblerDefault() const { return true; } 404 405 Tool *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 420 Tool *toolchains::MinGW::buildAssembler() const { 421 return new tools::MinGW::Assembler(*this); 422 } 423 424 Tool *toolchains::MinGW::buildLinker() const { 425 return new tools::MinGW::Linker(*this); 426 } 427 428 bool toolchains::MinGW::HasNativeLLVMSupport() const { 429 return NativeLLVMSupport; 430 } 431 432 bool 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 getArch() == llvm::Triple::aarch64; 441 } 442 443 bool toolchains::MinGW::isPICDefault() const { 444 return getArch() == llvm::Triple::x86_64; 445 } 446 447 bool toolchains::MinGW::isPIEDefault() const { return false; } 448 449 bool toolchains::MinGW::isPICDefaultForced() const { 450 return getArch() == llvm::Triple::x86_64; 451 } 452 453 llvm::ExceptionHandling 454 toolchains::MinGW::GetExceptionModel(const ArgList &Args) const { 455 if (getArch() == llvm::Triple::x86_64 || getArch() == llvm::Triple::aarch64) 456 return llvm::ExceptionHandling::WinEH; 457 return llvm::ExceptionHandling::DwarfCFI; 458 } 459 460 SanitizerMask toolchains::MinGW::getSupportedSanitizers() const { 461 SanitizerMask Res = ToolChain::getSupportedSanitizers(); 462 Res |= SanitizerKind::Address; 463 Res |= SanitizerKind::PointerCompare; 464 Res |= SanitizerKind::PointerSubtract; 465 return Res; 466 } 467 468 void toolchains::MinGW::AddCudaIncludeArgs(const ArgList &DriverArgs, 469 ArgStringList &CC1Args) const { 470 CudaInstallation.AddCudaIncludeArgs(DriverArgs, CC1Args); 471 } 472 473 void toolchains::MinGW::printVerboseInfo(raw_ostream &OS) const { 474 CudaInstallation.print(OS); 475 } 476 477 // Include directories for various hosts: 478 479 // Windows, mingw.org 480 // c:\mingw\lib\gcc\mingw32\4.8.1\include\c++ 481 // c:\mingw\lib\gcc\mingw32\4.8.1\include\c++\mingw32 482 // c:\mingw\lib\gcc\mingw32\4.8.1\include\c++\backward 483 // c:\mingw\include 484 // c:\mingw\mingw32\include 485 486 // Windows, mingw-w64 mingw-builds 487 // c:\mingw32\i686-w64-mingw32\include 488 // c:\mingw32\i686-w64-mingw32\include\c++ 489 // c:\mingw32\i686-w64-mingw32\include\c++\i686-w64-mingw32 490 // c:\mingw32\i686-w64-mingw32\include\c++\backward 491 492 // Windows, mingw-w64 msys2 493 // c:\msys64\mingw32\include 494 // c:\msys64\mingw32\i686-w64-mingw32\include 495 // c:\msys64\mingw32\include\c++\4.9.2 496 // c:\msys64\mingw32\include\c++\4.9.2\i686-w64-mingw32 497 // c:\msys64\mingw32\include\c++\4.9.2\backward 498 499 // openSUSE 500 // /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include/c++ 501 // /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include/c++/x86_64-w64-mingw32 502 // /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include/c++/backward 503 // /usr/x86_64-w64-mingw32/sys-root/mingw/include 504 505 // Arch Linux 506 // /usr/i686-w64-mingw32/include/c++/5.1.0 507 // /usr/i686-w64-mingw32/include/c++/5.1.0/i686-w64-mingw32 508 // /usr/i686-w64-mingw32/include/c++/5.1.0/backward 509 // /usr/i686-w64-mingw32/include 510 511 // Ubuntu 512 // /usr/include/c++/4.8 513 // /usr/include/c++/4.8/x86_64-w64-mingw32 514 // /usr/include/c++/4.8/backward 515 // /usr/x86_64-w64-mingw32/include 516 517 void toolchains::MinGW::AddClangSystemIncludeArgs(const ArgList &DriverArgs, 518 ArgStringList &CC1Args) const { 519 if (DriverArgs.hasArg(options::OPT_nostdinc)) 520 return; 521 522 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) { 523 SmallString<1024> P(getDriver().ResourceDir); 524 llvm::sys::path::append(P, "include"); 525 addSystemInclude(DriverArgs, CC1Args, P.str()); 526 } 527 528 if (DriverArgs.hasArg(options::OPT_nostdlibinc)) 529 return; 530 531 if (GetRuntimeLibType(DriverArgs) == ToolChain::RLT_Libgcc) { 532 // openSUSE 533 addSystemInclude(DriverArgs, CC1Args, 534 Base + Arch + "/sys-root/mingw/include"); 535 } 536 537 addSystemInclude(DriverArgs, CC1Args, 538 Base + Arch + llvm::sys::path::get_separator() + "include"); 539 addSystemInclude(DriverArgs, CC1Args, Base + "include"); 540 } 541 542 void toolchains::MinGW::AddClangCXXStdlibIncludeArgs( 543 const ArgList &DriverArgs, ArgStringList &CC1Args) const { 544 if (DriverArgs.hasArg(options::OPT_nostdlibinc) || 545 DriverArgs.hasArg(options::OPT_nostdincxx)) 546 return; 547 548 StringRef Slash = llvm::sys::path::get_separator(); 549 550 switch (GetCXXStdlibType(DriverArgs)) { 551 case ToolChain::CST_Libcxx: 552 addSystemInclude(DriverArgs, CC1Args, Base + Arch + Slash + "include" + 553 Slash + "c++" + Slash + "v1"); 554 addSystemInclude(DriverArgs, CC1Args, 555 Base + "include" + Slash + "c++" + Slash + "v1"); 556 break; 557 558 case ToolChain::CST_Libstdcxx: 559 llvm::SmallVector<llvm::SmallString<1024>, 4> CppIncludeBases; 560 CppIncludeBases.emplace_back(Base); 561 llvm::sys::path::append(CppIncludeBases[0], Arch, "include", "c++"); 562 CppIncludeBases.emplace_back(Base); 563 llvm::sys::path::append(CppIncludeBases[1], Arch, "include", "c++", Ver); 564 CppIncludeBases.emplace_back(Base); 565 llvm::sys::path::append(CppIncludeBases[2], "include", "c++", Ver); 566 CppIncludeBases.emplace_back(GccLibDir); 567 llvm::sys::path::append(CppIncludeBases[3], "include", "c++"); 568 for (auto &CppIncludeBase : CppIncludeBases) { 569 addSystemInclude(DriverArgs, CC1Args, CppIncludeBase); 570 CppIncludeBase += Slash; 571 addSystemInclude(DriverArgs, CC1Args, CppIncludeBase + Arch); 572 addSystemInclude(DriverArgs, CC1Args, CppIncludeBase + "backward"); 573 } 574 break; 575 } 576 } 577