| | 1 | --- a/tools/clang/lib/Driver/ToolChains/Darwin.cpp |
| | 2 | +++ b/tools/clang/lib/Driver/ToolChains/Darwin.cpp |
| | 3 | @@ -2021,21 +2021,42 @@ void DarwinClang::AddClangCXXStdlibIncludeArgs( |
| | 4 | |
| | 5 | switch (GetCXXStdlibType(DriverArgs)) { |
| | 6 | case ToolChain::CST_Libcxx: { |
| | 7 | - // On Darwin, libc++ is installed alongside the compiler in |
| | 8 | - // include/c++/v1, so get from '<install>/bin' to '<install>/include/c++/v1'. |
| | 9 | - { |
| | 10 | - llvm::SmallString<128> P = llvm::StringRef(getDriver().getInstalledDir()); |
| | 11 | - // Note that P can be relative, so we have to '..' and not parent_path. |
| | 12 | - llvm::sys::path::append(P, "..", "include", "c++", "v1"); |
| | 13 | - addSystemInclude(DriverArgs, CC1Args, P); |
| | 14 | + // On Darwin, libc++ can be installed in one of the following two places: |
| | 15 | + // 1. Alongside the compiler in <install>/include/c++/v1 |
| | 16 | + // 2. In a SDK (or a custom sysroot) in <sysroot>/usr/include/c++/v1 |
| | 17 | + // |
| | 18 | + // The precendence of paths is as listed above, i.e. we take the first path |
| | 19 | + // that exists. Also note that we never include libc++ twice -- we take the |
| | 20 | + // first path that exists and don't send the other paths to CC1 (otherwise |
| | 21 | + // include_next could break). |
| | 22 | + |
| | 23 | + // Check for (1) |
| | 24 | + // Get from '<install>/bin' to '<install>/include/c++/v1'. |
| | 25 | + // Note that InstallBin can be relative, so we use '..' instead of |
| | 26 | + // parent_path. |
| | 27 | + llvm::SmallString<128> InstallBin = |
| | 28 | + llvm::StringRef(getDriver().getInstalledDir()); // <install>/bin |
| | 29 | + llvm::sys::path::append(InstallBin, "..", "include", "c++", "v1"); |
| | 30 | + if (getVFS().exists(InstallBin)) { |
| | 31 | + addSystemInclude(DriverArgs, CC1Args, InstallBin); |
| | 32 | + return; |
| | 33 | + } else if (DriverArgs.hasArg(options::OPT_v)) { |
| | 34 | + llvm::errs() << "ignoring nonexistent directory \"" << InstallBin |
| | 35 | + << "\"\n"; |
| | 36 | } |
| | 37 | - // Also add <sysroot>/usr/include/c++/v1 unless -nostdinc is used, |
| | 38 | - // to match the legacy behavior in CC1. |
| | 39 | - if (!DriverArgs.hasArg(options::OPT_nostdinc)) { |
| | 40 | - llvm::SmallString<128> P = Sysroot; |
| | 41 | - llvm::sys::path::append(P, "usr", "include", "c++", "v1"); |
| | 42 | - addSystemInclude(DriverArgs, CC1Args, P); |
| | 43 | + |
| | 44 | + // Otherwise, check for (2) |
| | 45 | + llvm::SmallString<128> SysrootUsr = Sysroot; |
| | 46 | + llvm::sys::path::append(SysrootUsr, "usr", "include", "c++", "v1"); |
| | 47 | + if (getVFS().exists(SysrootUsr)) { |
| | 48 | + addSystemInclude(DriverArgs, CC1Args, SysrootUsr); |
| | 49 | + return; |
| | 50 | + } else if (DriverArgs.hasArg(options::OPT_v)) { |
| | 51 | + llvm::errs() << "ignoring nonexistent directory \"" << SysrootUsr |
| | 52 | + << "\"\n"; |
| | 53 | } |
| | 54 | + |
| | 55 | + // Otherwise, don't add any path. |
| | 56 | break; |
| | 57 | } |
| | 58 | |
| | 59 | --- a/tools/clang/test/Driver/darwin-header-search-libcxx.cpp |
| | 60 | +++ b/tools/clang/test/Driver/darwin-header-search-libcxx.cpp |
| | 61 | @@ -13,39 +13,57 @@ |
| | 62 | // RUN: | FileCheck --check-prefix=CHECK-LIBCXX-NONE %s |
| | 63 | // CHECK-LIBCXX-NONE: "{{[^"]*}}clang{{[^"]*}}" "-cc1" |
| | 64 | |
| | 65 | -// Check with only headers alongside the installation (those should be used, |
| | 66 | -// but we should still add /usr/include/c++/v1 after to preserve legacy). |
| | 67 | +// Check with only headers alongside the installation (those should be used). |
| | 68 | // |
| | 69 | // RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \ |
| | 70 | // RUN: -target x86_64-apple-darwin \ |
| | 71 | // RUN: -stdlib=libc++ \ |
| | 72 | // RUN: -ccc-install-dir %S/Inputs/basic_darwin_toolchain/usr/bin \ |
| | 73 | // RUN: --sysroot="" \ |
| | 74 | -// RUN: | FileCheck -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain --check-prefix=CHECK-LIBCXX-TOOLCHAIN-1 %s |
| | 75 | +// RUN: | FileCheck -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain \ |
| | 76 | +// RUN: --check-prefix=CHECK-LIBCXX-TOOLCHAIN-1 %s |
| | 77 | // CHECK-LIBCXX-TOOLCHAIN-1: "{{[^"]*}}clang{{[^"]*}}" "-cc1" |
| | 78 | // CHECK-LIBCXX-TOOLCHAIN-1: "-internal-isystem" "[[TOOLCHAIN]]/usr/bin/../include/c++/v1" |
| | 79 | -// CHECK-LIBCXX-TOOLCHAIN-1: "-internal-isystem" "/usr/include/c++/v1" |
| | 80 | +// CHECK-LIBCXX-TOOLCHAIN-1-NOT: "-internal-isystem" "/usr/include/c++/v1" |
| | 81 | // |
| | 82 | // RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \ |
| | 83 | // RUN: -target x86_64-apple-darwin \ |
| | 84 | // RUN: -stdlib=libc++ \ |
| | 85 | // RUN: -ccc-install-dir %S/Inputs/basic_darwin_toolchain/usr/bin \ |
| | 86 | // RUN: -isysroot %S/Inputs/basic_darwin_sdk_no_libcxx \ |
| | 87 | -// RUN: | FileCheck -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain --check-prefix=CHECK-LIBCXX-TOOLCHAIN-2 %s |
| | 88 | +// RUN: | FileCheck -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain \ |
| | 89 | +// RUN: -DSYSROOT=%S/Inputs/basic_darwin_sdk_no_libcxx \ |
| | 90 | +// RUN: --check-prefix=CHECK-LIBCXX-TOOLCHAIN-2 %s |
| | 91 | // CHECK-LIBCXX-TOOLCHAIN-2: "{{[^"]*}}clang{{[^"]*}}" "-cc1" |
| | 92 | // CHECK-LIBCXX-TOOLCHAIN-2: "-internal-isystem" "[[TOOLCHAIN]]/usr/bin/../include/c++/v1" |
| | 93 | +// CHECK-LIBCXX-TOOLCHAIN-2-NOT: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v1" |
| | 94 | + |
| | 95 | +// Check with only headers in the sysroot (those should be used). |
| | 96 | +// |
| | 97 | +// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \ |
| | 98 | +// RUN: -target x86_64-apple-darwin \ |
| | 99 | +// RUN: -stdlib=libc++ \ |
| | 100 | +// RUN: -ccc-install-dir %S/Inputs/basic_darwin_toolchain_no_libcxx/usr/bin \ |
| | 101 | +// RUN: -isysroot %S/Inputs/basic_darwin_sdk_usr_cxx_v1 \ |
| | 102 | +// RUN: | FileCheck -DSYSROOT=%S/Inputs/basic_darwin_sdk_usr_cxx_v1 \ |
| | 103 | +// RUN: -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain_no_libcxx \ |
| | 104 | +// RUN: --check-prefix=CHECK-LIBCXX-SYSROOT-1 %s |
| | 105 | +// CHECK-LIBCXX-SYSROOT-1: "{{[^"]*}}clang{{[^"]*}}" "-cc1" |
| | 106 | +// CHECK-LIBCXX-SYSROOT-1: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v1" |
| | 107 | +// CHECK-LIBCXX-SYSROOT-1-NOT: "-internal-isystem" "[[TOOLCHAIN]]/usr/bin/../include/c++/v1" |
| | 108 | |
| | 109 | // Check with both headers in the sysroot and headers alongside the installation |
| | 110 | -// (the headers in <sysroot> should be added after the toolchain headers). |
| | 111 | -// Ensure that both -isysroot and --sysroot work, and that isysroot has precedence. |
| | 112 | +// (the headers in the toolchain should be preferred over the <sysroot> headers). |
| | 113 | +// Ensure that both -isysroot and --sysroot work, and that isysroot has precedence |
| | 114 | +// over --sysroot. |
| | 115 | // |
| | 116 | // RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \ |
| | 117 | // RUN: -target x86_64-apple-darwin \ |
| | 118 | // RUN: -stdlib=libc++ \ |
| | 119 | // RUN: -ccc-install-dir %S/Inputs/basic_darwin_toolchain/usr/bin \ |
| | 120 | // RUN: -resource-dir=%S/Inputs/resource_dir \ |
| | 121 | -// RUN: -isysroot %S/Inputs/basic_darwin_sdk_usr \ |
| | 122 | -// RUN: | FileCheck -DSYSROOT=%S/Inputs/basic_darwin_sdk_usr \ |
| | 123 | +// RUN: -isysroot %S/Inputs/basic_darwin_sdk_usr_cxx_v1 \ |
| | 124 | +// RUN: | FileCheck -DSYSROOT=%S/Inputs/basic_darwin_sdk_usr_cxx_v1 \ |
| | 125 | // RUN: -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain \ |
| | 126 | // RUN: --check-prefix=CHECK-LIBCXX-SYSROOT_AND_TOOLCHAIN-1 %s |
| | 127 | // |
| | 128 | @@ -54,8 +72,8 @@ |
| | 129 | // RUN: -stdlib=libc++ \ |
| | 130 | // RUN: -ccc-install-dir %S/Inputs/basic_darwin_toolchain/usr/bin \ |
| | 131 | // RUN: -resource-dir=%S/Inputs/resource_dir \ |
| | 132 | -// RUN: --sysroot %S/Inputs/basic_darwin_sdk_usr \ |
| | 133 | -// RUN: | FileCheck -DSYSROOT=%S/Inputs/basic_darwin_sdk_usr \ |
| | 134 | +// RUN: --sysroot %S/Inputs/basic_darwin_sdk_usr_cxx_v1 \ |
| | 135 | +// RUN: | FileCheck -DSYSROOT=%S/Inputs/basic_darwin_sdk_usr_cxx_v1 \ |
| | 136 | // RUN: -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain \ |
| | 137 | // RUN: --check-prefix=CHECK-LIBCXX-SYSROOT_AND_TOOLCHAIN-1 %s |
| | 138 | // |
| | 139 | @@ -64,32 +82,46 @@ |
| | 140 | // RUN: -stdlib=libc++ \ |
| | 141 | // RUN: -ccc-install-dir %S/Inputs/basic_darwin_toolchain/usr/bin \ |
| | 142 | // RUN: -resource-dir=%S/Inputs/resource_dir \ |
| | 143 | -// RUN: -isysroot %S/Inputs/basic_darwin_sdk_usr \ |
| | 144 | +// RUN: -isysroot %S/Inputs/basic_darwin_sdk_usr_cxx_v1 \ |
| | 145 | // RUN: --sysroot %S/Inputs/basic_darwin_sdk_no_libcxx \ |
| | 146 | -// RUN: | FileCheck -DSYSROOT=%S/Inputs/basic_darwin_sdk_usr \ |
| | 147 | +// RUN: | FileCheck -DSYSROOT=%S/Inputs/basic_darwin_sdk_usr_cxx_v1 \ |
| | 148 | // RUN: -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain \ |
| | 149 | // RUN: --check-prefix=CHECK-LIBCXX-SYSROOT_AND_TOOLCHAIN-1 %s |
| | 150 | // |
| | 151 | // CHECK-LIBCXX-SYSROOT_AND_TOOLCHAIN-1: "{{[^"]*}}clang{{[^"]*}}" "-cc1" |
| | 152 | // CHECK-LIBCXX-SYSROOT_AND_TOOLCHAIN-1: "-internal-isystem" "[[TOOLCHAIN]]/usr/bin/../include/c++/v1" |
| | 153 | -// CHECK-LIBCXX-SYSROOT_AND_TOOLCHAIN-1: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v1" |
| | 154 | +// CHECK-LIBCXX-SYSROOT_AND_TOOLCHAIN-1-NOT: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v1" |
| | 155 | |
| | 156 | -// Make sure that using -nostdinc will drop the sysroot C++ library include |
| | 157 | -// path, but not the toolchain one. |
| | 158 | +// Make sure that using -nostdinc does not drop any C++ library include path. |
| | 159 | +// This behavior is strange, but it is compatible with the legacy CC1 behavior. |
| | 160 | // |
| | 161 | // RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \ |
| | 162 | // RUN: -target x86_64-apple-darwin16 \ |
| | 163 | // RUN: -ccc-install-dir %S/Inputs/basic_darwin_toolchain/usr/bin \ |
| | 164 | // RUN: -resource-dir=%S/Inputs/resource_dir \ |
| | 165 | -// RUN: -isysroot %S/Inputs/basic_darwin_sdk_usr \ |
| | 166 | +// RUN: -isysroot %S/Inputs/basic_darwin_sdk_usr_cxx_v1 \ |
| | 167 | // RUN: -stdlib=platform \ |
| | 168 | // RUN: -nostdinc \ |
| | 169 | -// RUN: | FileCheck -DSYSROOT=%S/Inputs/basic_darwin_sdk_usr \ |
| | 170 | +// RUN: | FileCheck -DSYSROOT=%S/Inputs/basic_darwin_sdk_usr_cxx_v1 \ |
| | 171 | // RUN: -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain \ |
| | 172 | -// RUN: --check-prefix=CHECK-LIBCXX-NOSTDINC %s |
| | 173 | -// CHECK-LIBCXX-NOSTDINC: "{{[^"]*}}clang{{[^"]*}}" "-cc1" |
| | 174 | -// CHECK-LIBCXX-NOSTDINC: "-internal-isystem" "[[TOOLCHAIN]]/usr/bin/../include/c++/v1" |
| | 175 | -// CHECK-LIBCXX-NOSTDINC-NOT: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v1" |
| | 176 | +// RUN: --check-prefix=CHECK-LIBCXX-NOSTDINC-1 %s |
| | 177 | +// CHECK-LIBCXX-NOSTDINC-1: "{{[^"]*}}clang{{[^"]*}}" "-cc1" |
| | 178 | +// CHECK-LIBCXX-NOSTDINC-1-NOT: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v1" |
| | 179 | +// CHECK-LIBCXX-NOSTDINC-1: "-internal-isystem" "[[TOOLCHAIN]]/usr/bin/../include/c++/v1" |
| | 180 | +// |
| | 181 | +// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \ |
| | 182 | +// RUN: -target x86_64-apple-darwin16 \ |
| | 183 | +// RUN: -ccc-install-dir %S/Inputs/basic_darwin_toolchain/usr/bin \ |
| | 184 | +// RUN: -resource-dir=%S/Inputs/resource_dir \ |
| | 185 | +// RUN: -isysroot %S/Inputs/basic_darwin_sdk_no_libcxx \ |
| | 186 | +// RUN: -stdlib=platform \ |
| | 187 | +// RUN: -nostdinc \ |
| | 188 | +// RUN: | FileCheck -DSYSROOT=%S/Inputs/basic_darwin_sdk_no_libcxx \ |
| | 189 | +// RUN: -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain \ |
| | 190 | +// RUN: --check-prefix=CHECK-LIBCXX-NOSTDINC-2 %s |
| | 191 | +// CHECK-LIBCXX-NOSTDINC-2: "{{[^"]*}}clang{{[^"]*}}" "-cc1" |
| | 192 | +// CHECK-LIBCXX-NOSTDINC-2: "-internal-isystem" "[[TOOLCHAIN]]/usr/bin/../include/c++/v1" |
| | 193 | +// CHECK-LIBCXX-NOSTDINC-2-NOT: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v1" |
| | 194 | |
| | 195 | // Make sure that using -nostdinc++ or -nostdlib will drop both the toolchain |
| | 196 | // C++ include path and the sysroot one. |
| | 197 | @@ -98,7 +130,7 @@ |
| | 198 | // RUN: -target x86_64-apple-darwin16 \ |
| | 199 | // RUN: -ccc-install-dir %S/Inputs/basic_darwin_toolchain/usr/bin \ |
| | 200 | // RUN: -resource-dir=%S/Inputs/resource_dir \ |
| | 201 | -// RUN: -isysroot %S/Inputs/basic_darwin_sdk_usr \ |
| | 202 | +// RUN: -isysroot %S/Inputs/basic_darwin_sdk_usr_cxx_v1 \ |
| | 203 | // RUN: -stdlib=platform \ |
| | 204 | // RUN: -nostdinc++ \ |
| | 205 | // RUN: | FileCheck -DSYSROOT=%S/Inputs/basic_darwin_sdk_usr \ |
| | 206 | @@ -121,3 +153,26 @@ |
| | 207 | // CHECK-LIBCXX-NOSTDLIBINC: "{{[^"]*}}clang{{[^"]*}}" "-cc1" |
| | 208 | // CHECK-LIBCXX-NOSTDLIBINC-NOT: "-internal-isystem" "[[TOOLCHAIN]]/usr/bin/../include/c++/v1" |
| | 209 | // CHECK-LIBCXX-NOSTDLIBINC-NOT: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v1" |
| | 210 | + |
| | 211 | +// Make sure we explain that we considered a path but didn't add it when it |
| | 212 | +// doesn't exist. |
| | 213 | +// |
| | 214 | +// RUN: %clang -no-canonical-prefixes %s -fsyntax-only -v 2>&1 \ |
| | 215 | +// RUN: -target x86_64-apple-darwin \ |
| | 216 | +// RUN: -ccc-install-dir %S/Inputs/basic_darwin_toolchain_no_libcxx/usr/bin \ |
| | 217 | +// RUN: -isysroot %S/Inputs/basic_darwin_sdk \ |
| | 218 | +// RUN: -stdlib=libc++ \ |
| | 219 | +// RUN: | FileCheck -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain_no_libcxx \ |
| | 220 | +// RUN: --check-prefix=CHECK-LIBCXX-MISSING-TOOLCHAIN %s |
| | 221 | +// CHECK-LIBCXX-MISSING-TOOLCHAIN: ignoring nonexistent directory "[[TOOLCHAIN]]/usr/bin/../include/c++/v1" |
| | 222 | +// |
| | 223 | +// RUN: %clang -no-canonical-prefixes %s -fsyntax-only -v 2>&1 \ |
| | 224 | +// RUN: -target x86_64-apple-darwin \ |
| | 225 | +// RUN: -ccc-install-dir %S/Inputs/basic_darwin_toolchain_no_libcxx/usr/bin \ |
| | 226 | +// RUN: -isysroot %S/Inputs/basic_darwin_sdk_no_libcxx \ |
| | 227 | +// RUN: -stdlib=libc++ \ |
| | 228 | +// RUN: | FileCheck -DSYSROOT=%S/Inputs/basic_darwin_sdk_no_libcxx \ |
| | 229 | +// RUN: -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain_no_libcxx \ |
| | 230 | +// RUN: --check-prefix=CHECK-LIBCXX-MISSING-BOTH %s |
| | 231 | +// CHECK-LIBCXX-MISSING-BOTH: ignoring nonexistent directory "[[TOOLCHAIN]]/usr/bin/../include/c++/v1" |
| | 232 | +// CHECK-LIBCXX-MISSING-BOTH: ignoring nonexistent directory "[[SYSROOT]]/usr/include/c++/v1" |