mstorsjo updated this revision to Diff 382946. mstorsjo marked an inline comment as done. mstorsjo added a comment.
Fixed the naming of the new function, using `--target=` in the newly added test lines, fixed a case of missed clang-format. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D111952/new/ https://reviews.llvm.org/D111952 Files: clang/lib/Driver/Driver.cpp clang/lib/Driver/ToolChains/MinGW.cpp clang/lib/Driver/ToolChains/MinGW.h clang/test/Driver/mingw-sysroot.cpp
Index: clang/test/Driver/mingw-sysroot.cpp =================================================================== --- clang/test/Driver/mingw-sysroot.cpp +++ clang/test/Driver/mingw-sysroot.cpp @@ -12,6 +12,7 @@ // RUN: mkdir -p %T/testroot-clang/bin // RUN: ln -s %clang %T/testroot-clang/bin/x86_64-w64-mingw32-clang // RUN: ln -s %S/Inputs/mingw_ubuntu_posix_tree/usr/x86_64-w64-mingw32 %T/testroot-clang/x86_64-w64-mingw32 +// RUN: ln -s %S/Inputs/mingw_arch_tree/usr/i686-w64-mingw32 %T/testroot-clang/i686-w64-mingw32 // If we find a gcc in the path with the right triplet prefix, pick that as @@ -36,3 +37,14 @@ // the libgcc directory: // RUN: env "PATH=%T/testroot-gcc/bin:%PATH%" %T/testroot-gcc/bin/x86_64-w64-mingw32-clang -target x86_64-w64-mingw32 -rtlib=platform -stdlib=libstdc++ --sysroot="" -c -### %s 2>&1 | FileCheck -check-prefix=CHECK_TESTROOT_GCC %s + + +// If the user requests a different arch via the -m32 option, which changes +// x86_64 into i386, check that the driver notices that it can't find a +// sysroot for i386 but there is one for i686, and uses that one. +// (In practice, the real usecase is when using an unprefixed native clang +// that defaults to x86_64 mingw, but it's easier to test this in cross setups +// with symlinks, like the other tests here.) + +// RUN: env "PATH=%T/testroot-gcc/bin:%PATH%" %T/testroot-clang/bin/x86_64-w64-mingw32-clang --target=x86_64-w64-mingw32 -m32 -rtlib=compiler-rt -stdlib=libstdc++ --sysroot="" -c -### %s 2>&1 | FileCheck -check-prefix=CHECK_TESTROOT_CLANG_I686 %s +// CHECK_TESTROOT_CLANG_I686: "{{[^"]+}}/testroot-clang{{/|\\\\}}i686-w64-mingw32{{/|\\\\}}include" Index: clang/lib/Driver/ToolChains/MinGW.h =================================================================== --- clang/lib/Driver/ToolChains/MinGW.h +++ clang/lib/Driver/ToolChains/MinGW.h @@ -60,6 +60,9 @@ MinGW(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args); + static void fixTripleArch(const Driver &D, llvm::Triple &Triple, + const llvm::opt::ArgList &Args); + bool HasNativeLLVMSupport() const override; bool IsIntegratedAssemblerDefault() const override; @@ -103,8 +106,6 @@ mutable std::unique_ptr<tools::gcc::Preprocessor> Preprocessor; mutable std::unique_ptr<tools::gcc::Compiler> Compiler; void findGccLibDir(); - llvm::ErrorOr<std::string> findGcc(); - llvm::ErrorOr<std::string> findClangRelativeSysroot(); bool NativeLLVMSupport; }; Index: clang/lib/Driver/ToolChains/MinGW.cpp =================================================================== --- clang/lib/Driver/ToolChains/MinGW.cpp +++ clang/lib/Driver/ToolChains/MinGW.cpp @@ -369,9 +369,9 @@ } } -llvm::ErrorOr<std::string> toolchains::MinGW::findGcc() { +static llvm::ErrorOr<std::string> findGcc(const llvm::Triple &T) { llvm::SmallVector<llvm::SmallString<32>, 2> Gccs; - Gccs.emplace_back(getTriple().getArchName()); + Gccs.emplace_back(T.getArchName()); Gccs[0] += "-w64-mingw32-gcc"; Gccs.emplace_back("mingw32-gcc"); // Please do not add "gcc" here @@ -381,13 +381,14 @@ return make_error_code(std::errc::no_such_file_or_directory); } -llvm::ErrorOr<std::string> toolchains::MinGW::findClangRelativeSysroot() { +static llvm::ErrorOr<std::string> +findClangRelativeSysroot(const Driver &D, const llvm::Triple &T, + std::string &SubdirName) { llvm::SmallVector<llvm::SmallString<32>, 2> Subdirs; - Subdirs.emplace_back(getTriple().str()); - Subdirs.emplace_back(getTriple().getArchName()); + Subdirs.emplace_back(T.str()); + Subdirs.emplace_back(T.getArchName()); Subdirs[1] += "-w64-mingw32"; - StringRef ClangRoot = - llvm::sys::path::parent_path(getDriver().getInstalledDir()); + StringRef ClangRoot = llvm::sys::path::parent_path(D.getInstalledDir()); StringRef Sep = llvm::sys::path::get_separator(); for (StringRef CandidateSubdir : Subdirs) { if (llvm::sys::fs::is_directory(ClangRoot + Sep + CandidateSubdir)) { @@ -404,13 +405,16 @@ RocmInstallation(D, Triple, Args) { getProgramPaths().push_back(getDriver().getInstalledDir()); + // The sequence for detecting a sysroot here should be kept in sync with + // the testTriple function below. if (getDriver().SysRoot.size()) Base = getDriver().SysRoot; // Look for <clang-bin>/../<triplet>; if found, use <clang-bin>/.. as the // base as it could still be a base for a gcc setup with libgcc. - else if (llvm::ErrorOr<std::string> TargetSubdir = findClangRelativeSysroot()) + else if (llvm::ErrorOr<std::string> TargetSubdir = + findClangRelativeSysroot(getDriver(), getTriple(), SubdirName)) Base = std::string(llvm::sys::path::parent_path(TargetSubdir.get())); - else if (llvm::ErrorOr<std::string> GPPName = findGcc()) + else if (llvm::ErrorOr<std::string> GPPName = findGcc(getTriple())) Base = std::string(llvm::sys::path::parent_path( llvm::sys::path::parent_path(GPPName.get()))); else @@ -625,3 +629,55 @@ break; } } + +static bool testTriple(const Driver &D, const llvm::Triple &Triple, + const ArgList &Args) { + // If an explicit sysroot is set, that will be used and we shouldn't try to + // detect anything else. + std::string SubdirName; + if (D.SysRoot.size()) + return true; + if (llvm::ErrorOr<std::string> TargetSubdir = + findClangRelativeSysroot(D, Triple, SubdirName)) + return true; + if (llvm::ErrorOr<std::string> GPPName = findGcc(Triple)) + return true; + // If we neither found a colocated sysroot or a matching gcc executable, + // conclude that we can't know if this is the correct spelling of the triple. + return false; +} + +static llvm::Triple adjustTriple(const Driver &D, const llvm::Triple &Triple, + const ArgList &Args) { + // First test if the original triple can find a sysroot with the triple + // name. + if (testTriple(D, Triple, Args)) + return Triple; + llvm::SmallVector<llvm::StringRef, 3> Archs; + // If not, test a couple other possible arch names that might be what was + // intended. + if (Triple.getArch() == llvm::Triple::x86) { + Archs.emplace_back("i386"); + Archs.emplace_back("i586"); + Archs.emplace_back("i686"); + } else if (Triple.getArch() == llvm::Triple::arm || + Triple.getArch() == llvm::Triple::thumb) { + Archs.emplace_back("armv7"); + } + for (auto A : Archs) { + llvm::Triple TestTriple(Triple); + TestTriple.setArchName(A); + if (testTriple(D, TestTriple, Args)) + return TestTriple; + } + // If none was found, just proceed with the original value. + return Triple; +} + +void toolchains::MinGW::fixTripleArch(const Driver &D, llvm::Triple &Triple, + const ArgList &Args) { + if (Triple.getArch() == llvm::Triple::x86 || + Triple.getArch() == llvm::Triple::arm || + Triple.getArch() == llvm::Triple::thumb) + Triple = adjustTriple(D, Triple, Args); +} Index: clang/lib/Driver/Driver.cpp =================================================================== --- clang/lib/Driver/Driver.cpp +++ clang/lib/Driver/Driver.cpp @@ -525,8 +525,11 @@ Target.setEnvironment(llvm::Triple::CODE16); } - if (AT != llvm::Triple::UnknownArch && AT != Target.getArch()) + if (AT != llvm::Triple::UnknownArch && AT != Target.getArch()) { Target.setArch(AT); + if (Target.isWindowsGNUEnvironment()) + toolchains::MinGW::fixTripleArch(D, Target, Args); + } } // Handle -miamcu flag.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits