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 const char *OutputFile = Output.getFilename(); 164 // GCC implicitly adds an .exe extension if it is given an output file name 165 // that lacks an extension. However, GCC only does this when actually 166 // running on windows, not when operating as a cross compiler. As some users 167 // have come to rely on this behaviour, try to replicate it. 168 #ifdef _WIN32 169 if (!llvm::sys::path::has_extension(OutputFile)) 170 CmdArgs.push_back(Args.MakeArgString(Twine(OutputFile) + ".exe")); 171 else 172 CmdArgs.push_back(OutputFile); 173 #else 174 CmdArgs.push_back(OutputFile); 175 #endif 176 177 Args.AddAllArgs(CmdArgs, options::OPT_e); 178 // FIXME: add -N, -n flags 179 Args.AddLastArg(CmdArgs, options::OPT_r); 180 Args.AddLastArg(CmdArgs, options::OPT_s); 181 Args.AddLastArg(CmdArgs, options::OPT_t); 182 Args.AddAllArgs(CmdArgs, options::OPT_u_Group); 183 Args.AddLastArg(CmdArgs, options::OPT_Z_Flag); 184 185 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) { 186 if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_mdll)) { 187 CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("dllcrt2.o"))); 188 } else { 189 if (Args.hasArg(options::OPT_municode)) 190 CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crt2u.o"))); 191 else 192 CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crt2.o"))); 193 } 194 if (Args.hasArg(options::OPT_pg)) 195 CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("gcrt2.o"))); 196 CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crtbegin.o"))); 197 } 198 199 Args.AddAllArgs(CmdArgs, options::OPT_L); 200 TC.AddFilePathLibArgs(Args, CmdArgs); 201 AddLinkerInputs(TC, Inputs, Args, CmdArgs, JA); 202 203 // TODO: Add profile stuff here 204 205 if (TC.ShouldLinkCXXStdlib(Args)) { 206 bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) && 207 !Args.hasArg(options::OPT_static); 208 if (OnlyLibstdcxxStatic) 209 CmdArgs.push_back("-Bstatic"); 210 TC.AddCXXStdlibLibArgs(Args, CmdArgs); 211 if (OnlyLibstdcxxStatic) 212 CmdArgs.push_back("-Bdynamic"); 213 } 214 215 bool HasWindowsApp = false; 216 for (auto Lib : Args.getAllArgValues(options::OPT_l)) { 217 if (Lib == "windowsapp") { 218 HasWindowsApp = true; 219 break; 220 } 221 } 222 223 if (!Args.hasArg(options::OPT_nostdlib)) { 224 if (!Args.hasArg(options::OPT_nodefaultlibs)) { 225 if (Args.hasArg(options::OPT_static)) 226 CmdArgs.push_back("--start-group"); 227 228 if (Args.hasArg(options::OPT_fstack_protector) || 229 Args.hasArg(options::OPT_fstack_protector_strong) || 230 Args.hasArg(options::OPT_fstack_protector_all)) { 231 CmdArgs.push_back("-lssp_nonshared"); 232 CmdArgs.push_back("-lssp"); 233 } 234 235 if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ, 236 options::OPT_fno_openmp, false)) { 237 switch (TC.getDriver().getOpenMPRuntime(Args)) { 238 case Driver::OMPRT_OMP: 239 CmdArgs.push_back("-lomp"); 240 break; 241 case Driver::OMPRT_IOMP5: 242 CmdArgs.push_back("-liomp5md"); 243 break; 244 case Driver::OMPRT_GOMP: 245 CmdArgs.push_back("-lgomp"); 246 break; 247 case Driver::OMPRT_Unknown: 248 // Already diagnosed. 249 break; 250 } 251 } 252 253 AddLibGCC(Args, CmdArgs); 254 255 if (Args.hasArg(options::OPT_pg)) 256 CmdArgs.push_back("-lgmon"); 257 258 if (Args.hasArg(options::OPT_pthread)) 259 CmdArgs.push_back("-lpthread"); 260 261 if (Sanitize.needsAsanRt()) { 262 // MinGW always links against a shared MSVCRT. 263 CmdArgs.push_back(TC.getCompilerRTArgString(Args, "asan_dynamic", 264 ToolChain::FT_Shared)); 265 CmdArgs.push_back( 266 TC.getCompilerRTArgString(Args, "asan_dynamic_runtime_thunk")); 267 CmdArgs.push_back("--require-defined"); 268 CmdArgs.push_back(TC.getArch() == llvm::Triple::x86 269 ? "___asan_seh_interceptor" 270 : "__asan_seh_interceptor"); 271 // Make sure the linker consider all object files from the dynamic 272 // runtime thunk. 273 CmdArgs.push_back("--whole-archive"); 274 CmdArgs.push_back( 275 TC.getCompilerRTArgString(Args, "asan_dynamic_runtime_thunk")); 276 CmdArgs.push_back("--no-whole-archive"); 277 } 278 279 TC.addProfileRTLibs(Args, CmdArgs); 280 281 if (!HasWindowsApp) { 282 // Add system libraries. If linking to libwindowsapp.a, that import 283 // library replaces all these and we shouldn't accidentally try to 284 // link to the normal desktop mode dlls. 285 if (Args.hasArg(options::OPT_mwindows)) { 286 CmdArgs.push_back("-lgdi32"); 287 CmdArgs.push_back("-lcomdlg32"); 288 } 289 CmdArgs.push_back("-ladvapi32"); 290 CmdArgs.push_back("-lshell32"); 291 CmdArgs.push_back("-luser32"); 292 CmdArgs.push_back("-lkernel32"); 293 } 294 295 if (Args.hasArg(options::OPT_static)) 296 CmdArgs.push_back("--end-group"); 297 else 298 AddLibGCC(Args, CmdArgs); 299 } 300 301 if (!Args.hasArg(options::OPT_nostartfiles)) { 302 // Add crtfastmath.o if available and fast math is enabled. 303 TC.AddFastMathRuntimeIfAvailable(Args, CmdArgs); 304 305 CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crtend.o"))); 306 } 307 } 308 const char *Exec = Args.MakeArgString(TC.GetLinkerPath()); 309 C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs)); 310 } 311 312 // Simplified from Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple. 313 static bool findGccVersion(StringRef LibDir, std::string &GccLibDir, 314 std::string &Ver) { 315 auto Version = toolchains::Generic_GCC::GCCVersion::Parse("0.0.0"); 316 std::error_code EC; 317 for (llvm::sys::fs::directory_iterator LI(LibDir, EC), LE; !EC && LI != LE; 318 LI = LI.increment(EC)) { 319 StringRef VersionText = llvm::sys::path::filename(LI->path()); 320 auto CandidateVersion = 321 toolchains::Generic_GCC::GCCVersion::Parse(VersionText); 322 if (CandidateVersion.Major == -1) 323 continue; 324 if (CandidateVersion <= Version) 325 continue; 326 Ver = VersionText; 327 GccLibDir = LI->path(); 328 } 329 return Ver.size(); 330 } 331 332 void toolchains::MinGW::findGccLibDir() { 333 llvm::SmallVector<llvm::SmallString<32>, 2> Archs; 334 Archs.emplace_back(getTriple().getArchName()); 335 Archs[0] += "-w64-mingw32"; 336 Archs.emplace_back("mingw32"); 337 if (Arch.empty()) 338 Arch = Archs[0].str(); 339 // lib: Arch Linux, Ubuntu, Windows 340 // lib64: openSUSE Linux 341 for (StringRef CandidateLib : {"lib", "lib64"}) { 342 for (StringRef CandidateArch : Archs) { 343 llvm::SmallString<1024> LibDir(Base); 344 llvm::sys::path::append(LibDir, CandidateLib, "gcc", CandidateArch); 345 if (findGccVersion(LibDir, GccLibDir, Ver)) { 346 Arch = CandidateArch; 347 return; 348 } 349 } 350 } 351 } 352 353 llvm::ErrorOr<std::string> toolchains::MinGW::findGcc() { 354 llvm::SmallVector<llvm::SmallString<32>, 2> Gccs; 355 Gccs.emplace_back(getTriple().getArchName()); 356 Gccs[0] += "-w64-mingw32-gcc"; 357 Gccs.emplace_back("mingw32-gcc"); 358 // Please do not add "gcc" here 359 for (StringRef CandidateGcc : Gccs) 360 if (llvm::ErrorOr<std::string> GPPName = llvm::sys::findProgramByName(CandidateGcc)) 361 return GPPName; 362 return make_error_code(std::errc::no_such_file_or_directory); 363 } 364 365 llvm::ErrorOr<std::string> toolchains::MinGW::findClangRelativeSysroot() { 366 llvm::SmallVector<llvm::SmallString<32>, 2> Subdirs; 367 Subdirs.emplace_back(getTriple().str()); 368 Subdirs.emplace_back(getTriple().getArchName()); 369 Subdirs[1] += "-w64-mingw32"; 370 StringRef ClangRoot = 371 llvm::sys::path::parent_path(getDriver().getInstalledDir()); 372 StringRef Sep = llvm::sys::path::get_separator(); 373 for (StringRef CandidateSubdir : Subdirs) { 374 if (llvm::sys::fs::is_directory(ClangRoot + Sep + CandidateSubdir)) { 375 Arch = CandidateSubdir; 376 return (ClangRoot + Sep + CandidateSubdir).str(); 377 } 378 } 379 return make_error_code(std::errc::no_such_file_or_directory); 380 } 381 382 toolchains::MinGW::MinGW(const Driver &D, const llvm::Triple &Triple, 383 const ArgList &Args) 384 : ToolChain(D, Triple, Args), CudaInstallation(D, Triple, Args) { 385 getProgramPaths().push_back(getDriver().getInstalledDir()); 386 387 if (getDriver().SysRoot.size()) 388 Base = getDriver().SysRoot; 389 // Look for <clang-bin>/../<triplet>; if found, use <clang-bin>/.. as the 390 // base as it could still be a base for a gcc setup with libgcc. 391 else if (llvm::ErrorOr<std::string> TargetSubdir = findClangRelativeSysroot()) 392 Base = llvm::sys::path::parent_path(TargetSubdir.get()); 393 else if (llvm::ErrorOr<std::string> GPPName = findGcc()) 394 Base = llvm::sys::path::parent_path( 395 llvm::sys::path::parent_path(GPPName.get())); 396 else 397 Base = llvm::sys::path::parent_path(getDriver().getInstalledDir()); 398 399 Base += llvm::sys::path::get_separator(); 400 findGccLibDir(); 401 // GccLibDir must precede Base/lib so that the 402 // correct crtbegin.o ,cetend.o would be found. 403 getFilePaths().push_back(GccLibDir); 404 getFilePaths().push_back( 405 (Base + Arch + llvm::sys::path::get_separator() + "lib").str()); 406 getFilePaths().push_back(Base + "lib"); 407 // openSUSE 408 getFilePaths().push_back(Base + Arch + "/sys-root/mingw/lib"); 409 410 NativeLLVMSupport = 411 Args.getLastArgValue(options::OPT_fuse_ld_EQ, CLANG_DEFAULT_LINKER) 412 .equals_lower("lld"); 413 } 414 415 bool toolchains::MinGW::IsIntegratedAssemblerDefault() const { return true; } 416 417 Tool *toolchains::MinGW::getTool(Action::ActionClass AC) const { 418 switch (AC) { 419 case Action::PreprocessJobClass: 420 if (!Preprocessor) 421 Preprocessor.reset(new tools::gcc::Preprocessor(*this)); 422 return Preprocessor.get(); 423 case Action::CompileJobClass: 424 if (!Compiler) 425 Compiler.reset(new tools::gcc::Compiler(*this)); 426 return Compiler.get(); 427 default: 428 return ToolChain::getTool(AC); 429 } 430 } 431 432 Tool *toolchains::MinGW::buildAssembler() const { 433 return new tools::MinGW::Assembler(*this); 434 } 435 436 Tool *toolchains::MinGW::buildLinker() const { 437 return new tools::MinGW::Linker(*this); 438 } 439 440 bool toolchains::MinGW::HasNativeLLVMSupport() const { 441 return NativeLLVMSupport; 442 } 443 444 bool toolchains::MinGW::IsUnwindTablesDefault(const ArgList &Args) const { 445 Arg *ExceptionArg = Args.getLastArg(options::OPT_fsjlj_exceptions, 446 options::OPT_fseh_exceptions, 447 options::OPT_fdwarf_exceptions); 448 if (ExceptionArg && 449 ExceptionArg->getOption().matches(options::OPT_fseh_exceptions)) 450 return true; 451 return getArch() == llvm::Triple::x86_64 || 452 getArch() == llvm::Triple::aarch64; 453 } 454 455 bool toolchains::MinGW::isPICDefault() const { 456 return getArch() == llvm::Triple::x86_64; 457 } 458 459 bool toolchains::MinGW::isPIEDefault() const { return false; } 460 461 bool toolchains::MinGW::isPICDefaultForced() const { 462 return getArch() == llvm::Triple::x86_64; 463 } 464 465 llvm::ExceptionHandling 466 toolchains::MinGW::GetExceptionModel(const ArgList &Args) const { 467 if (getArch() == llvm::Triple::x86_64 || getArch() == llvm::Triple::aarch64) 468 return llvm::ExceptionHandling::WinEH; 469 return llvm::ExceptionHandling::DwarfCFI; 470 } 471 472 SanitizerMask toolchains::MinGW::getSupportedSanitizers() const { 473 SanitizerMask Res = ToolChain::getSupportedSanitizers(); 474 Res |= SanitizerKind::Address; 475 Res |= SanitizerKind::PointerCompare; 476 Res |= SanitizerKind::PointerSubtract; 477 return Res; 478 } 479 480 void toolchains::MinGW::AddCudaIncludeArgs(const ArgList &DriverArgs, 481 ArgStringList &CC1Args) const { 482 CudaInstallation.AddCudaIncludeArgs(DriverArgs, CC1Args); 483 } 484 485 void toolchains::MinGW::printVerboseInfo(raw_ostream &OS) const { 486 CudaInstallation.print(OS); 487 } 488 489 // Include directories for various hosts: 490 491 // Windows, mingw.org 492 // c:\mingw\lib\gcc\mingw32\4.8.1\include\c++ 493 // c:\mingw\lib\gcc\mingw32\4.8.1\include\c++\mingw32 494 // c:\mingw\lib\gcc\mingw32\4.8.1\include\c++\backward 495 // c:\mingw\include 496 // c:\mingw\mingw32\include 497 498 // Windows, mingw-w64 mingw-builds 499 // c:\mingw32\i686-w64-mingw32\include 500 // c:\mingw32\i686-w64-mingw32\include\c++ 501 // c:\mingw32\i686-w64-mingw32\include\c++\i686-w64-mingw32 502 // c:\mingw32\i686-w64-mingw32\include\c++\backward 503 504 // Windows, mingw-w64 msys2 505 // c:\msys64\mingw32\include 506 // c:\msys64\mingw32\i686-w64-mingw32\include 507 // c:\msys64\mingw32\include\c++\4.9.2 508 // c:\msys64\mingw32\include\c++\4.9.2\i686-w64-mingw32 509 // c:\msys64\mingw32\include\c++\4.9.2\backward 510 511 // openSUSE 512 // /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include/c++ 513 // /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include/c++/x86_64-w64-mingw32 514 // /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include/c++/backward 515 // /usr/x86_64-w64-mingw32/sys-root/mingw/include 516 517 // Arch Linux 518 // /usr/i686-w64-mingw32/include/c++/5.1.0 519 // /usr/i686-w64-mingw32/include/c++/5.1.0/i686-w64-mingw32 520 // /usr/i686-w64-mingw32/include/c++/5.1.0/backward 521 // /usr/i686-w64-mingw32/include 522 523 // Ubuntu 524 // /usr/include/c++/4.8 525 // /usr/include/c++/4.8/x86_64-w64-mingw32 526 // /usr/include/c++/4.8/backward 527 // /usr/x86_64-w64-mingw32/include 528 529 void toolchains::MinGW::AddClangSystemIncludeArgs(const ArgList &DriverArgs, 530 ArgStringList &CC1Args) const { 531 if (DriverArgs.hasArg(options::OPT_nostdinc)) 532 return; 533 534 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) { 535 SmallString<1024> P(getDriver().ResourceDir); 536 llvm::sys::path::append(P, "include"); 537 addSystemInclude(DriverArgs, CC1Args, P.str()); 538 } 539 540 if (DriverArgs.hasArg(options::OPT_nostdlibinc)) 541 return; 542 543 if (GetRuntimeLibType(DriverArgs) == ToolChain::RLT_Libgcc) { 544 // openSUSE 545 addSystemInclude(DriverArgs, CC1Args, 546 Base + Arch + "/sys-root/mingw/include"); 547 } 548 549 addSystemInclude(DriverArgs, CC1Args, 550 Base + Arch + llvm::sys::path::get_separator() + "include"); 551 addSystemInclude(DriverArgs, CC1Args, Base + "include"); 552 } 553 554 void toolchains::MinGW::AddClangCXXStdlibIncludeArgs( 555 const ArgList &DriverArgs, ArgStringList &CC1Args) const { 556 if (DriverArgs.hasArg(options::OPT_nostdlibinc) || 557 DriverArgs.hasArg(options::OPT_nostdincxx)) 558 return; 559 560 StringRef Slash = llvm::sys::path::get_separator(); 561 562 switch (GetCXXStdlibType(DriverArgs)) { 563 case ToolChain::CST_Libcxx: 564 addSystemInclude(DriverArgs, CC1Args, Base + Arch + Slash + "include" + 565 Slash + "c++" + Slash + "v1"); 566 addSystemInclude(DriverArgs, CC1Args, 567 Base + "include" + Slash + "c++" + Slash + "v1"); 568 break; 569 570 case ToolChain::CST_Libstdcxx: 571 llvm::SmallVector<llvm::SmallString<1024>, 4> CppIncludeBases; 572 CppIncludeBases.emplace_back(Base); 573 llvm::sys::path::append(CppIncludeBases[0], Arch, "include", "c++"); 574 CppIncludeBases.emplace_back(Base); 575 llvm::sys::path::append(CppIncludeBases[1], Arch, "include", "c++", Ver); 576 CppIncludeBases.emplace_back(Base); 577 llvm::sys::path::append(CppIncludeBases[2], "include", "c++", Ver); 578 CppIncludeBases.emplace_back(GccLibDir); 579 llvm::sys::path::append(CppIncludeBases[3], "include", "c++"); 580 for (auto &CppIncludeBase : CppIncludeBases) { 581 addSystemInclude(DriverArgs, CC1Args, CppIncludeBase); 582 CppIncludeBase += Slash; 583 addSystemInclude(DriverArgs, CC1Args, CppIncludeBase + Arch); 584 addSystemInclude(DriverArgs, CC1Args, CppIncludeBase + "backward"); 585 } 586 break; 587 } 588 } 589