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