Index: lib/Driver/ToolChains.h =================================================================== --- lib/Driver/ToolChains.h +++ lib/Driver/ToolChains.h @@ -145,13 +145,6 @@ const std::string &LibDir, StringRef CandidateTriple, bool NeedsBiarchSuffix = false); - - bool findMIPSMultilibs(const llvm::Triple &TargetArch, StringRef Path, - const llvm::opt::ArgList &Args); - - bool findBiarchMultilibs(const llvm::Triple &TargetArch, StringRef Path, - const llvm::opt::ArgList &Args, - bool NeedsBiarchSuffix); }; GCCInstallationDetector GCCInstallation; Index: lib/Driver/ToolChains.cpp =================================================================== --- lib/Driver/ToolChains.cpp +++ lib/Driver/ToolChains.cpp @@ -1646,9 +1646,21 @@ return A && A->getValue() == StringRef("2008"); } -bool Generic_GCC::GCCInstallationDetector::findMIPSMultilibs( - const llvm::Triple &TargetTriple, StringRef Path, - const llvm::opt::ArgList &Args) { +struct DetectedMultilibs { + /// The set of multilibs that the detected installation supports. + MultilibSet Multilibs; + + /// The primary multilib appropriate for the given flags. + Multilib SelectedMultilib; + + /// On Biarch systems, this corresponds to the default multilib when + /// targeting the non-default multilib. Otherwise, it is empty. + llvm::Optional BiarchSibling; +}; + +static bool findMIPSMultilibs(const llvm::Triple &TargetTriple, StringRef Path, + const llvm::opt::ArgList &Args, + DetectedMultilibs &Result) { // Some MIPS toolchains put libraries and object files compiled // using different options in to the sub-directoris which names // reflects the flags used for compilation. For example sysroot @@ -1877,9 +1889,10 @@ if (TargetTriple.getEnvironment() == llvm::Triple::Android) { // Select Android toolchain. It's the only choice in that case. - Multilibs.clear(); - Multilibs.combineWith(AndroidMipsMultilibs); - return Multilibs.select(Flags, SelectedMultilib); + Result.Multilibs.combineWith(AndroidMipsMultilibs); + if (Result.Multilibs.select(Flags, Result.SelectedMultilib)) + return true; + return false; } // Sort candidates. Toolchain that best meets the directories goes first. @@ -1890,11 +1903,10 @@ std::begin(candidates), std::end(candidates), [](MultilibSet *a, MultilibSet *b) { return a->size() > b->size(); }); for (const auto &candidate : candidates) { - Multilibs.clear(); - Multilibs.combineWith(*candidate); - if (Multilibs.select(Flags, SelectedMultilib)) { + Result.Multilibs.combineWith(*candidate); + if (Result.Multilibs.select(Flags, Result.SelectedMultilib)) { if (candidate == &DebianMipsMultilibs) - BiarchSibling = Multilib(); + Result.BiarchSibling = Multilib(); return true; } } @@ -1902,9 +1914,10 @@ return false; } -bool Generic_GCC::GCCInstallationDetector::findBiarchMultilibs( - const llvm::Triple &TargetTriple, StringRef Path, const ArgList &Args, - bool NeedsBiarchSuffix) { +static bool findBiarchMultilibs(const llvm::Triple &TargetTriple, + StringRef Path, const ArgList &Args, + bool NeedsBiarchSuffix, + DetectedMultilibs &Result) { // Some versions of SUSE and Fedora on ppc64 put 32-bit libs // in what would normally be GCCInstallPath and put the 64-bit @@ -1944,22 +1957,21 @@ else Default.flag("-m32").flag("+m64"); - Multilibs.push_back(Default); - Multilibs.push_back(Alt64); - Multilibs.push_back(Alt32); + Result.Multilibs.push_back(Default); + Result.Multilibs.push_back(Alt64); + Result.Multilibs.push_back(Alt32); - Multilibs.FilterOut(NonExistent); + Result.Multilibs.FilterOut(NonExistent); Multilib::flags_list Flags; addMultilibFlag(TargetTriple.isArch64Bit(), "m64", Flags); addMultilibFlag(TargetTriple.isArch32Bit(), "m32", Flags); - if (!Multilibs.select(Flags, SelectedMultilib)) + if (!Result.Multilibs.select(Flags, Result.SelectedMultilib)) return false; - if (SelectedMultilib == Alt64 || SelectedMultilib == Alt32) { - BiarchSibling = Default; - } + if (Result.SelectedMultilib == Alt64 || Result.SelectedMultilib == Alt32) + Result.BiarchSibling = Default; return true; } @@ -2013,19 +2025,21 @@ if (CandidateVersion <= Version) continue; - Multilibs.clear(); - SelectedMultilib = Multilib(); - BiarchSibling.reset(); + DetectedMultilibs Detected; // Debian mips multilibs behave more like the rest of the biarch ones, // so handle them there if (isMipsArch(TargetArch)) { - if (!findMIPSMultilibs(TargetTriple, LI->path(), Args)) + if (!findMIPSMultilibs(TargetTriple, LI->path(), Args, Detected)) continue; } else if (!findBiarchMultilibs(TargetTriple, LI->path(), Args, - NeedsBiarchSuffix)) + NeedsBiarchSuffix, Detected)) { continue; + } + Multilibs = Detected.Multilibs; + SelectedMultilib = Detected.SelectedMultilib; + BiarchSibling = Detected.BiarchSibling; Version = CandidateVersion; GCCTriple.setTriple(CandidateTriple); // FIXME: We hack together the directory name here instead of Index: test/Driver/linux-header-search.cpp =================================================================== --- test/Driver/linux-header-search.cpp +++ test/Driver/linux-header-search.cpp @@ -81,6 +81,20 @@ // CHECK-UBUNTU-13-04-M32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/backward" // CHECK-UBUNTU-13-04-M32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/x86_64-linux-gnu/c++/4.7/32" // +// Test Ubuntu/Debian's Ubuntu 14.04 config variant, with -m32 +// and an empty 4.9 directory. +// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \ +// RUN: -target x86_64-unknown-linux-gnu -m32 \ +// RUN: --sysroot=%S/Inputs/ubuntu_14.04_multiarch_tree \ +// RUN: | FileCheck --check-prefix=CHECK-UBUNTU-14-04-M32 %s +// CHECK-UBUNTU-14-04-M32: "{{[^"]*}}clang{{[^"]*}}" "-cc1" +// CHECK-UBUNTU-14-04-M32: "-triple" "i386-unknown-linux-gnu" +// CHECK-UBUNTU-14-04-M32: "-isysroot" "[[SYSROOT:[^"]+]]" +// CHECK-UBUNTU-14-04-M32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8" +// CHECK-UBUNTU-14-04-M32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/x86_64-linux-gnu/32" +// CHECK-UBUNTU-14-04-M32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/backward" +// CHECK-UBUNTU-14-04-M32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/x86_64-linux-gnu/c++/4.8/32" +// // Thoroughly exercise the Debian multiarch environment. // RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \ // RUN: -target i686-linux-gnu \