Add Multilib selection machinery

This patch improves the support for picking Multilibs from gcc installations.
It also provides a better approximation for the flags '-print-multi-directory'
and '-print-multi-lib'.

This reverts r201203 (i.e. re-applying r201202 with small fixes in
unittests/CMakeLists.txtto make the build bots happy).

review: http://llvm-reviews.chandlerc.com/D2538
llvm-svn: 201205
diff --git a/clang/lib/Driver/ToolChains.h b/clang/lib/Driver/ToolChains.h
index d5d0581..6c3b084 100644
--- a/clang/lib/Driver/ToolChains.h
+++ b/clang/lib/Driver/ToolChains.h
@@ -13,8 +13,10 @@
 #include "Tools.h"
 #include "clang/Basic/VersionTuple.h"
 #include "clang/Driver/Action.h"
+#include "clang/Driver/Multilib.h"
 #include "clang/Driver/ToolChain.h"
 #include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/Optional.h"
 #include "llvm/Support/Compiler.h"
 #include <set>
 #include <vector>
@@ -67,7 +69,6 @@
     bool operator>=(const GCCVersion &RHS) const { return !(*this < RHS); }
   };
 
-
   /// \brief This is a class to find a viable GCC installation for Clang to
   /// use.
   ///
@@ -80,9 +81,13 @@
 
     // FIXME: These might be better as path objects.
     std::string GCCInstallPath;
-    std::string GCCBiarchSuffix;
     std::string GCCParentLibPath;
-    std::string GCCMIPSABIDirSuffix;
+
+    /// 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<Multilib> BiarchSibling;
 
     GCCVersion Version;
 
@@ -90,6 +95,9 @@
     // order to print out detailed information in verbose mode.
     std::set<std::string> CandidateGCCInstallPaths;
 
+    /// The set of multilibs that the detected installation supports.
+    MultilibSet Multilibs;
+
   public:
     GCCInstallationDetector() : IsValid(false) {}
     void init(const Driver &D, const llvm::Triple &TargetTriple,
@@ -104,26 +112,18 @@
     /// \brief Get the detected GCC installation path.
     StringRef getInstallPath() const { return GCCInstallPath; }
 
-    /// \brief Get the detected GCC installation path suffix for the bi-arch
-    /// target variant.
-    StringRef getBiarchSuffix() const { return GCCBiarchSuffix; }
-
     /// \brief Get the detected GCC parent lib path.
     StringRef getParentLibPath() const { return GCCParentLibPath; }
 
-    /// \brief Get the detected GCC MIPS ABI directory suffix.
-    ///
-    /// This is used as a suffix both to the install directory of GCC and as
-    /// a suffix to its parent lib path in order to select a MIPS ABI-specific
-    /// subdirectory.
-    ///
-    /// This will always be empty for any non-MIPS target.
-    ///
-    // FIXME: This probably shouldn't exist at all, and should be factored
-    // into the multiarch and/or biarch support. Please don't add more uses of
-    // this interface, it is meant as a legacy crutch for the MIPS driver
-    // logic.
-    StringRef getMIPSABIDirSuffix() const { return GCCMIPSABIDirSuffix; }
+    /// \brief Get the detected Multilib
+    const Multilib &getMultilib() const { return SelectedMultilib; }
+
+    /// \brief Get the whole MultilibSet
+    const MultilibSet &getMultilibs() const { return Multilibs; }
+
+    /// Get the biarch sibling multilib (if it exists).
+    /// \return true iff such a sibling exists
+    bool getBiarchSibling(Multilib &M) const;
 
     /// \brief Get the detected GCC version string.
     const GCCVersion &getVersion() const { return Version; }
@@ -140,15 +140,18 @@
                              SmallVectorImpl<StringRef> &BiarchLibDirs,
                              SmallVectorImpl<StringRef> &BiarchTripleAliases);
 
-    void ScanLibDirForGCCTriple(llvm::Triple::ArchType TargetArch,
+    void ScanLibDirForGCCTriple(const llvm::Triple &TargetArch,
                                 const llvm::opt::ArgList &Args,
                                 const std::string &LibDir,
                                 StringRef CandidateTriple,
                                 bool NeedsBiarchSuffix = false);
 
-    void findMIPSABIDirSuffix(std::string &Suffix,
-                              llvm::Triple::ArchType TargetArch, StringRef Path,
-                              const llvm::opt::ArgList &Args);
+    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;
@@ -665,9 +668,7 @@
 
 private:
   static bool addLibStdCXXIncludePaths(Twine Base, Twine Suffix,
-                                       Twine TargetArchDir,
-                                       Twine BiarchSuffix,
-                                       Twine MIPSABIDirSuffix,
+                                       Twine TargetArchDir, Twine IncludeSuffix,
                                        const llvm::opt::ArgList &DriverArgs,
                                        llvm::opt::ArgStringList &CC1Args);
   static bool addLibStdCXXIncludePaths(Twine Base, Twine TargetArchDir,