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