Driver: add support for new style multiarch in Ubuntu 13.04

Patch by Sanne Wouda.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@176557 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp
index 3cd1a34..035af21 100644
--- a/lib/Driver/ToolChains.cpp
+++ b/lib/Driver/ToolChains.cpp
@@ -2597,7 +2597,7 @@
   addExternCSystemInclude(DriverArgs, CC1Args, D.SysRoot + "/usr/include");
 }
 
-/// \brief Helper to add the thre variant paths for a libstdc++ installation.
+/// \brief Helper to add the three variant paths for a libstdc++ installation.
 /*static*/ bool Linux::addLibStdCXXIncludePaths(Twine Base, Twine TargetArchDir,
                                                 const ArgList &DriverArgs,
                                                 ArgStringList &CC1Args) {
@@ -2609,6 +2609,22 @@
   return true;
 }
 
+/// \brief Helper to add an extra variant path for an (Ubuntu) multilib
+/// libstdc++ installation.
+/*static*/ bool Linux::addLibStdCXXIncludePaths(Twine Base, Twine Suffix,
+                                                Twine TargetArchDir,
+                                                Twine MultiLibSuffix,
+                                                const ArgList &DriverArgs,
+                                                ArgStringList &CC1Args) {
+  if (!addLibStdCXXIncludePaths(Base+Suffix, TargetArchDir + MultiLibSuffix,
+                                DriverArgs, CC1Args))
+    return false;
+
+  addSystemInclude(DriverArgs, CC1Args, Base + "/" + TargetArchDir + Suffix
+                   + MultiLibSuffix);
+  return true;
+}
+
 void Linux::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
                                          ArgStringList &CC1Args) const {
   if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
@@ -2636,8 +2652,14 @@
   StringRef Version = GCCInstallation.getVersion().Text;
   StringRef TripleStr = GCCInstallation.getTriple().str();
 
+  if (addLibStdCXXIncludePaths(LibDir.str() + "/../include", 
+                               "/c++/" + Version.str(),
+                               TripleStr,
+                               GCCInstallation.getMultiarchSuffix(),
+                               DriverArgs, CC1Args))
+    return;
+
   const std::string IncludePathCandidates[] = {
-    LibDir.str() + "/../include/c++/" + Version.str(),
     // Gentoo is weird and places its headers inside the GCC install, so if the
     // first attempt to find the headers fails, try this pattern.
     InstallDir.str() + "/include/g++-v4",
diff --git a/lib/Driver/ToolChains.h b/lib/Driver/ToolChains.h
index b84525f..0419a37 100644
--- a/lib/Driver/ToolChains.h
+++ b/lib/Driver/ToolChains.h
@@ -501,6 +501,11 @@
   std::vector<std::string> ExtraOpts;
 
 private:
+  static bool addLibStdCXXIncludePaths(Twine Base, Twine Suffix,
+                                       Twine TargetArchDir,
+                                       Twine MultiLibSuffix,
+                                       const ArgList &DriverArgs,
+                                       ArgStringList &CC1Args);
   static bool addLibStdCXXIncludePaths(Twine Base, Twine TargetArchDir,
                                        const ArgList &DriverArgs,
                                        ArgStringList &CC1Args);
diff --git a/test/Driver/Inputs/ubuntu_13.04_multiarch_tree/lib/x86_64-linux-gnu/.keep b/test/Driver/Inputs/ubuntu_13.04_multiarch_tree/lib/x86_64-linux-gnu/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/ubuntu_13.04_multiarch_tree/lib/x86_64-linux-gnu/.keep
diff --git a/test/Driver/Inputs/ubuntu_13.04_multiarch_tree/usr/include/c++/4.7/backward/.keep b/test/Driver/Inputs/ubuntu_13.04_multiarch_tree/usr/include/c++/4.7/backward/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/ubuntu_13.04_multiarch_tree/usr/include/c++/4.7/backward/.keep
diff --git a/test/Driver/Inputs/ubuntu_13.04_multiarch_tree/usr/include/x86_64-linux-gnu/c++/4.7/.keep b/test/Driver/Inputs/ubuntu_13.04_multiarch_tree/usr/include/x86_64-linux-gnu/c++/4.7/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/ubuntu_13.04_multiarch_tree/usr/include/x86_64-linux-gnu/c++/4.7/.keep
diff --git a/test/Driver/Inputs/ubuntu_13.04_multiarch_tree/usr/include/x86_64-linux-gnu/c++/4.7/32/.keep b/test/Driver/Inputs/ubuntu_13.04_multiarch_tree/usr/include/x86_64-linux-gnu/c++/4.7/32/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/ubuntu_13.04_multiarch_tree/usr/include/x86_64-linux-gnu/c++/4.7/32/.keep
diff --git a/test/Driver/Inputs/ubuntu_13.04_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/4.7/32/.keep b/test/Driver/Inputs/ubuntu_13.04_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/4.7/32/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/ubuntu_13.04_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/4.7/32/.keep
diff --git a/test/Driver/Inputs/ubuntu_13.04_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/4.7/32/crtbegin.o b/test/Driver/Inputs/ubuntu_13.04_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/4.7/32/crtbegin.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/ubuntu_13.04_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/4.7/32/crtbegin.o
diff --git a/test/Driver/Inputs/ubuntu_13.04_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/4.7/crtbegin.o b/test/Driver/Inputs/ubuntu_13.04_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/4.7/crtbegin.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/ubuntu_13.04_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/4.7/crtbegin.o
diff --git a/test/Driver/linux-header-search.cpp b/test/Driver/linux-header-search.cpp
index 065bd34..d09f5b2 100644
--- a/test/Driver/linux-header-search.cpp
+++ b/test/Driver/linux-header-search.cpp
@@ -16,6 +16,34 @@
 // CHECK-UBUNTU-11-04: "-internal-externc-isystem" "[[SYSROOT]]/include"
 // CHECK-UBUNTU-11-04: "-internal-externc-isystem" "[[SYSROOT]]/usr/include"
 //
+// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \
+// RUN:     -target x86_64-unknown-linux-gnu \
+// RUN:     --sysroot=%S/Inputs/ubuntu_13.04_multiarch_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-UBUNTU-13-04 %s
+// CHECK-UBUNTU-13-04: "{{[^"]*}}clang{{[^"]*}}" "-cc1"
+// CHECK-UBUNTU-13-04: "-isysroot" "[[SYSROOT:[^"]+]]"
+// CHECK-UBUNTU-13-04: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7"
+// CHECK-UBUNTU-13-04: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/backward"
+// CHECK-UBUNTU-13-04: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/x86_64-linux-gnu/c++/4.7"
+// CHECK-UBUNTU-13-04: "-internal-isystem" "[[SYSROOT]]/usr/local/include"
+// CHECK-UBUNTU-13-04: "-internal-isystem" "{{.*}}/lib{{(64|32)?}}/clang/{{[0-9]\.[0-9]}}/include"
+// CHECK-UBUNTU-13-04: "-internal-externc-isystem" "[[SYSROOT]]/usr/include/x86_64-linux-gnu"
+// CHECK-UBUNTU-13-04: "-internal-externc-isystem" "[[SYSROOT]]/include"
+// CHECK-UBUNTU-13-04: "-internal-externc-isystem" "[[SYSROOT]]/usr/include"
+//
+// Test Ubuntu/Debian's new version of multiarch, with -m32.
+// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \
+// RUN:     -target x86_64-unknown-linux-gnu -m32 \
+// RUN:     --sysroot=%S/Inputs/ubuntu_13.04_multiarch_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-UBUNTU-13-04-M32 %s
+// CHECK-UBUNTU-13-04-M32: "{{[^"]*}}clang{{[^"]*}}" "-cc1"
+// CHECK-UBUNTU-13-04-M32: "-triple" "i386-unknown-linux-gnu"
+// CHECK-UBUNTU-13-04-M32: "-isysroot" "[[SYSROOT:[^"]+]]"
+// CHECK-UBUNTU-13-04-M32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7"
+// CHECK-UBUNTU-13-04-M32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/x86_64-linux-gnu/32"
+// 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"
+//
 // Thoroughly exercise the Debian multiarch environment.
 // RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \
 // RUN:     -target i686-linux-gnu \