diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp --- a/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/clang/lib/Driver/ToolChains/Gnu.cpp @@ -2086,7 +2086,10 @@ "x86_64-manbo-linux-gnu", "x86_64-linux-gnu", "x86_64-slackware-linux", "x86_64-unknown-linux", "x86_64-amazon-linux", "x86_64-linux-android"}; - static const char *const X32LibDirs[] = {"/libx32"}; + static const char *const X32LibDirs[] = {"/libx32", "/lib"}; + static const char *const X32Triples[] = { + "x86_64-linux-gnux32", "x86_64-unknown-linux-gnux32", + "x86_64-pc-linux-gnux32"}; static const char *const X86LibDirs[] = {"/lib32", "/lib"}; static const char *const X86Triples[] = { "i686-linux-gnu", "i686-pc-linux-gnu", "i486-linux-gnu", @@ -2307,14 +2310,16 @@ TripleAliases.append(begin(AVRTriples), end(AVRTriples)); break; case llvm::Triple::x86_64: - LibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs)); - TripleAliases.append(begin(X86_64Triples), end(X86_64Triples)); // x32 is always available when x86_64 is available, so adding it as // secondary arch with x86_64 triples if (TargetTriple.getEnvironment() == llvm::Triple::GNUX32) { - BiarchLibDirs.append(begin(X32LibDirs), end(X32LibDirs)); + LibDirs.append(begin(X32LibDirs), end(X32LibDirs)); + TripleAliases.append(begin(X32Triples), end(X32Triples)); + BiarchLibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs)); BiarchTripleAliases.append(begin(X86_64Triples), end(X86_64Triples)); } else { + LibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs)); + TripleAliases.append(begin(X86_64Triples), end(X86_64Triples)); BiarchLibDirs.append(begin(X86LibDirs), end(X86LibDirs)); BiarchTripleAliases.append(begin(X86Triples), end(X86Triples)); } diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp --- a/clang/lib/Driver/ToolChains/Linux.cpp +++ b/clang/lib/Driver/ToolChains/Linux.cpp @@ -87,10 +87,13 @@ case llvm::Triple::x86_64: if (IsAndroid) return "x86_64-linux-android"; - // We don't want this for x32, otherwise it will match x86_64 libs - if (TargetEnvironment != llvm::Triple::GNUX32 && - D.getVFS().exists(SysRoot + "/lib/x86_64-linux-gnu")) - return "x86_64-linux-gnu"; + if (TargetEnvironment == llvm::Triple::GNUX32) { + if (D.getVFS().exists(SysRoot + "/lib/x86_64-linux-gnux32")) + return "x86_64-linux-gnux32"; + } else { + if (D.getVFS().exists(SysRoot + "/lib/x86_64-linux-gnu")) + return "x86_64-linux-gnu"; + } break; case llvm::Triple::aarch64: if (IsAndroid) @@ -599,6 +602,8 @@ // in use in any released version of Debian, so we should consider // removing them. "/usr/include/i686-linux-gnu/64", "/usr/include/i486-linux-gnu/64"}; + const StringRef X32MultiarchIncludeDirs[] = { + "/usr/include/x86_64-linux-gnux32"}; const StringRef X86MultiarchIncludeDirs[] = { "/usr/include/i386-linux-gnu", @@ -656,7 +661,10 @@ ArrayRef MultiarchIncludeDirs; switch (getTriple().getArch()) { case llvm::Triple::x86_64: - MultiarchIncludeDirs = X86_64MultiarchIncludeDirs; + if (getTriple().getEnvironment() == llvm::Triple::GNUX32) + MultiarchIncludeDirs = X32MultiarchIncludeDirs; + else + MultiarchIncludeDirs = X86_64MultiarchIncludeDirs; break; case llvm::Triple::x86: MultiarchIncludeDirs = X86MultiarchIncludeDirs; diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/lib/x86_64-linux-gnux32/.keep b/clang/test/Driver/Inputs/debian_multiarch_tree/lib/x86_64-linux-gnux32/.keep new file mode 100644 diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/usr/include/c++/4.5/x86_64-linux-gnux32/.keep b/clang/test/Driver/Inputs/debian_multiarch_tree/usr/include/c++/4.5/x86_64-linux-gnux32/.keep new file mode 100644 diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/usr/include/x86_64-linux-gnux32/.keep b/clang/test/Driver/Inputs/debian_multiarch_tree/usr/include/x86_64-linux-gnux32/.keep new file mode 100644 diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/gcc/x86_64-linux-gnux32/4.5/crtbegin.o b/clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/gcc/x86_64-linux-gnux32/4.5/crtbegin.o new file mode 100644 diff --git a/clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/x86_64-linux-gnux32/.keep b/clang/test/Driver/Inputs/debian_multiarch_tree/usr/lib/x86_64-linux-gnux32/.keep new file mode 100644 diff --git a/clang/test/Driver/linux-header-search.cpp b/clang/test/Driver/linux-header-search.cpp --- a/clang/test/Driver/linux-header-search.cpp +++ b/clang/test/Driver/linux-header-search.cpp @@ -224,7 +224,23 @@ // CHECK-DEBIAN-X86-64: "-internal-isystem" "[[RESOURCE_DIR]]{{/|\\\\}}include" // CHECK-DEBIAN-X86-64: "-internal-externc-isystem" "[[SYSROOT]]/usr/include/x86_64-linux-gnu" // CHECK-DEBIAN-X86-64: "-internal-externc-isystem" "[[SYSROOT]]/include" -// CHECK-DEBIAN-X86-64: "-internal-externc-isystem" "[[SYSROOT]]/usr/include" +// CHECK-DEBIAN-X86-64: "-internal-externc-isystem" "[[SYSROOT]]/usr/include +// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \ +// RUN: -target x86_64-linux-gnux32 -stdlib=libstdc++ \ +// RUN: --sysroot=%S/Inputs/debian_multiarch_tree \ +// RUN: --gcc-toolchain="" \ +// RUN: | FileCheck --check-prefix=CHECK-DEBIAN-X32 %s +// CHECK-DEBIAN-X32: "{{[^"]*}}clang{{[^"]*}}" "-cc1" +// CHECK-DEBIAN-X32: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK-DEBIAN-X32: "-isysroot" "[[SYSROOT:[^"]+]]" +// CHECK-DEBIAN-X32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnux32/4.5/../../../../include/c++/4.5" +// CHECK-DEBIAN-X32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnux32/4.5/../../../../include/c++/4.5/x86_64-linux-gnux32" +// CHECK-DEBIAN-X32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnux32/4.5/../../../../include/c++/4.5/backward" +// CHECK-DEBIAN-X32: "-internal-isystem" "[[SYSROOT]]/usr/local/include" +// CHECK-DEBIAN-X32: "-internal-isystem" "[[RESOURCE_DIR]]{{/|\\\\}}include" +// CHECK-DEBIAN-X32: "-internal-externc-isystem" "[[SYSROOT]]/usr/include/x86_64-linux-gnux32" +// CHECK-DEBIAN-X32: "-internal-externc-isystem" "[[SYSROOT]]/include" +// CHECK-DEBIAN-X32: "-internal-externc-isystem" "[[SYSROOT]]/usr/include" // RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \ // RUN: -target powerpc-linux-gnu -stdlib=libstdc++ \ // RUN: --sysroot=%S/Inputs/debian_multiarch_tree \ diff --git a/clang/test/Driver/linux-ld.c b/clang/test/Driver/linux-ld.c --- a/clang/test/Driver/linux-ld.c +++ b/clang/test/Driver/linux-ld.c @@ -1170,6 +1170,19 @@ // CHECK-DEBIAN-X86-64: "-L[[SYSROOT]]/lib" // CHECK-DEBIAN-X86-64: "-L[[SYSROOT]]/usr/lib" // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: --target=x86_64-linux-gnux32 -rtlib=platform \ +// RUN: --gcc-toolchain="" \ +// RUN: --sysroot=%S/Inputs/debian_multiarch_tree \ +// RUN: | FileCheck --check-prefix=CHECK-DEBIAN-X32 %s +// CHECK-DEBIAN-X32: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" +// CHECK-DEBIAN-X32: "{{.*}}/usr/lib/gcc/x86_64-linux-gnux32/4.5{{/|\\\\}}crtbegin.o" +// CHECK-DEBIAN-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnux32/4.5" +// CHECK-DEBIAN-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnux32/4.5/../../../x86_64-linux-gnux32" +// CHECK-DEBIAN-X32: "-L[[SYSROOT]]/usr/lib/x86_64-linux-gnux32" +// CHECK-DEBIAN-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnux32/4.5/../../.." +// CHECK-DEBIAN-X32: "-L[[SYSROOT]]/lib" +// CHECK-DEBIAN-X32: "-L[[SYSROOT]]/usr/lib" +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: --target=powerpc-linux-gnu -rtlib=platform \ // RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/debian_multiarch_tree \