| 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" |