diff --git a/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/empty-sysroot/.gitkeep b/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/empty-sysroot/.gitkeep new file mode 100644 diff --git a/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/mock-libcxx/bin/clang b/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/mock-toolchain-root/bin/clang rename from clang-tools-extra/test/clang-tidy/infrastructure/Inputs/mock-libcxx/bin/clang rename to clang-tools-extra/test/clang-tidy/infrastructure/Inputs/mock-toolchain-root/bin/clang diff --git a/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/mock-libcxx/include/c++/v1/mock_vector b/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/mock-toolchain-root/include/c++/v1/mock_vector rename from clang-tools-extra/test/clang-tidy/infrastructure/Inputs/mock-libcxx/include/c++/v1/mock_vector rename to clang-tools-extra/test/clang-tidy/infrastructure/Inputs/mock-toolchain-root/include/c++/v1/mock_vector diff --git a/clang-tools-extra/test/clang-tidy/infrastructure/clang-tidy-mac-libcxx.cpp b/clang-tools-extra/test/clang-tidy/infrastructure/clang-tidy-mac-libcxx.cpp --- a/clang-tools-extra/test/clang-tidy/infrastructure/clang-tidy-mac-libcxx.cpp +++ b/clang-tools-extra/test/clang-tidy/infrastructure/clang-tidy-mac-libcxx.cpp @@ -1,14 +1,18 @@ -// Clang on MacOS can find libc++ living beside the installed compiler. -// This test makes sure clang-tidy emulates this properly. +// Clang on MacOS can find libc++ living beside the installed compiler if there +// are no headers in the sysroot. This test makes sure our clang-tidy emulates +// this properly. // // RUN: rm -rf %t // RUN: mkdir %t // -// Install the mock libc++ (simulates the libc++ directory structure). -// RUN: cp -r %S/Inputs/mock-libcxx %t/ +// Install a mock toolchain root that contains a simulation of libc++. +// RUN: cp -r %S/Inputs/mock-toolchain-root %t/mock-toolchain-root // -// Pretend clang is installed beside the mock library that we provided. -// RUN: echo '[{"directory":"%t","command":"%t/mock-libcxx/bin/clang++ -stdlib=libc++ -std=c++11 -target x86_64-apple-darwin -c test.cpp","file":"test.cpp"}]' | sed -e 's/\\/\//g' > %t/compile_commands.json +// Install a mock sysroot that doesn't contain anything, to make sure we +// prefer the libc++ headers in the toolchain. +// RUN: cp -r %S/Inputs/empty-sysroot %t/empty-sysroot +// +// RUN: echo '[{"directory":"%t","command":"%t/mock-toolchain-root/bin/clang -isysroot %t/empty-sysroot -stdlib=libc++ -std=c++11 -target x86_64-apple-darwin -c test.cpp","file":"test.cpp"}]' | sed -e 's/\\/\//g' > %t/compile_commands.json // RUN: cp "%s" "%t/test.cpp" // RUN: clang-tidy -header-filter='.*' -system-headers -checks='-*,modernize-use-using' "%t/test.cpp" | FileCheck %s // CHECK: mock_vector:{{[0-9]+}}:{{[0-9]+}}: warning: use 'using' instead of 'typedef' diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp --- a/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/clang/lib/Driver/ToolChains/Darwin.cpp @@ -2021,8 +2021,8 @@ switch (GetCXXStdlibType(DriverArgs)) { case ToolChain::CST_Libcxx: { // On Darwin, libc++ can be installed in one of the following two places: - // 1. Alongside the compiler in /include/c++/v1 - // 2. In a SDK (or a custom sysroot) in /usr/include/c++/v1 + // 1. In a SDK (or a custom sysroot) in /usr/include/c++/v1 + // 2. Alongside the compiler in /include/c++/v1 // // The precendence of paths is as listed above, i.e. we take the first path // that exists. Also note that we never include libc++ twice -- we take the @@ -2030,6 +2030,17 @@ // include_next could break). // Check for (1) + llvm::SmallString<128> SysrootUsr = Sysroot; + llvm::sys::path::append(SysrootUsr, "usr", "include", "c++", "v1"); + if (getVFS().exists(SysrootUsr)) { + addSystemInclude(DriverArgs, CC1Args, SysrootUsr); + return; + } else if (DriverArgs.hasArg(options::OPT_v)) { + llvm::errs() << "ignoring nonexistent directory \"" << SysrootUsr + << "\"\n"; + } + + // Otherwise, check for (2) // Get from '/bin' to '/include/c++/v1'. // Note that InstallBin can be relative, so we use '..' instead of // parent_path. @@ -2044,17 +2055,6 @@ << "\"\n"; } - // Otherwise, check for (2) - llvm::SmallString<128> SysrootUsr = Sysroot; - llvm::sys::path::append(SysrootUsr, "usr", "include", "c++", "v1"); - if (getVFS().exists(SysrootUsr)) { - addSystemInclude(DriverArgs, CC1Args, SysrootUsr); - return; - } else if (DriverArgs.hasArg(options::OPT_v)) { - llvm::errs() << "ignoring nonexistent directory \"" << SysrootUsr - << "\"\n"; - } - // Otherwise, don't add any path. break; } diff --git a/clang/test/Driver/darwin-header-search-libcxx.cpp b/clang/test/Driver/darwin-header-search-libcxx.cpp --- a/clang/test/Driver/darwin-header-search-libcxx.cpp +++ b/clang/test/Driver/darwin-header-search-libcxx.cpp @@ -53,7 +53,7 @@ // CHECK-LIBCXX-SYSROOT-1-NOT: "-internal-isystem" "[[TOOLCHAIN]]/usr/bin/../include/c++/v1" // Check with both headers in the sysroot and headers alongside the installation -// (the headers in the toolchain should be preferred over the headers). +// (the headers in should be preferred over the toolchain headers). // Ensure that both -isysroot and --sysroot work, and that isysroot has precedence // over --sysroot. // @@ -89,8 +89,8 @@ // RUN: --check-prefix=CHECK-LIBCXX-SYSROOT_AND_TOOLCHAIN-1 %s // // CHECK-LIBCXX-SYSROOT_AND_TOOLCHAIN-1: "{{[^"]*}}clang{{[^"]*}}" "-cc1" -// CHECK-LIBCXX-SYSROOT_AND_TOOLCHAIN-1: "-internal-isystem" "[[TOOLCHAIN]]/usr/bin/../include/c++/v1" -// CHECK-LIBCXX-SYSROOT_AND_TOOLCHAIN-1-NOT: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v1" +// CHECK-LIBCXX-SYSROOT_AND_TOOLCHAIN-1: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v1" +// CHECK-LIBCXX-SYSROOT_AND_TOOLCHAIN-1-NOT: "-internal-isystem" "[[TOOLCHAIN]]/usr/bin/../include/c++/v1" // Make sure that using -nostdinc does not drop any C++ library include path. // This behavior is strange, but it is compatible with the legacy CC1 behavior. @@ -106,8 +106,8 @@ // RUN: -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain \ // RUN: --check-prefix=CHECK-LIBCXX-NOSTDINC-1 %s // CHECK-LIBCXX-NOSTDINC-1: "{{[^"]*}}clang{{[^"]*}}" "-cc1" -// CHECK-LIBCXX-NOSTDINC-1-NOT: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v1" -// CHECK-LIBCXX-NOSTDINC-1: "-internal-isystem" "[[TOOLCHAIN]]/usr/bin/../include/c++/v1" +// CHECK-LIBCXX-NOSTDINC-1-NOT: "-internal-isystem" "[[TOOLCHAIN]]/usr/bin/../include/c++/v1" +// CHECK-LIBCXX-NOSTDINC-1: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v1" // // RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \ // RUN: -target x86_64-apple-darwin16 \ @@ -159,11 +159,11 @@ // // RUN: %clang -no-canonical-prefixes %s -fsyntax-only -v 2>&1 \ // RUN: -target x86_64-apple-darwin \ -// RUN: -ccc-install-dir %S/Inputs/basic_darwin_toolchain_no_libcxx/usr/bin \ -// RUN: -isysroot %S/Inputs/basic_darwin_sdk \ -// RUN: | FileCheck -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain_no_libcxx \ -// RUN: --check-prefix=CHECK-LIBCXX-MISSING-TOOLCHAIN %s -// CHECK-LIBCXX-MISSING-TOOLCHAIN: ignoring nonexistent directory "[[TOOLCHAIN]]/usr/bin/../include/c++/v1" +// RUN: -ccc-install-dir %S/Inputs/basic_darwin_toolchain/usr/bin \ +// RUN: -isysroot %S/Inputs/basic_darwin_sdk_no_libcxx \ +// RUN: | FileCheck -DSYSROOT=%S/Inputs/basic_darwin_sdk_no_libcxx \ +// RUN: --check-prefix=CHECK-LIBCXX-MISSING-SYSROOT %s +// CHECK-LIBCXX-MISSING-SYSROOT: ignoring nonexistent directory "[[SYSROOT]]/usr/include/c++/v1" // // RUN: %clang -no-canonical-prefixes %s -fsyntax-only -v 2>&1 \ // RUN: -target x86_64-apple-darwin \ @@ -172,5 +172,5 @@ // RUN: | FileCheck -DSYSROOT=%S/Inputs/basic_darwin_sdk_no_libcxx \ // RUN: -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain_no_libcxx \ // RUN: --check-prefix=CHECK-LIBCXX-MISSING-BOTH %s -// CHECK-LIBCXX-MISSING-BOTH: ignoring nonexistent directory "[[TOOLCHAIN]]/usr/bin/../include/c++/v1" // CHECK-LIBCXX-MISSING-BOTH: ignoring nonexistent directory "[[SYSROOT]]/usr/include/c++/v1" +// CHECK-LIBCXX-MISSING-BOTH: ignoring nonexistent directory "[[TOOLCHAIN]]/usr/bin/../include/c++/v1" diff --git a/clang/test/Tooling/Inputs/empty-sysroot/.gitkeep b/clang/test/Tooling/Inputs/empty-sysroot/.gitkeep new file mode 100644 diff --git a/clang/test/Tooling/Inputs/mock-libcxx/bin/clang b/clang/test/Tooling/Inputs/mock-toolchain-root/bin/clang rename from clang/test/Tooling/Inputs/mock-libcxx/bin/clang rename to clang/test/Tooling/Inputs/mock-toolchain-root/bin/clang diff --git a/clang/test/Tooling/Inputs/mock-libcxx/include/c++/v1/mock_vector b/clang/test/Tooling/Inputs/mock-toolchain-root/include/c++/v1/mock_vector rename from clang/test/Tooling/Inputs/mock-libcxx/include/c++/v1/mock_vector rename to clang/test/Tooling/Inputs/mock-toolchain-root/include/c++/v1/mock_vector diff --git a/clang/test/Tooling/clang-check-mac-libcxx-abspath.cpp b/clang/test/Tooling/clang-check-mac-libcxx-abspath.cpp --- a/clang/test/Tooling/clang-check-mac-libcxx-abspath.cpp +++ b/clang/test/Tooling/clang-check-mac-libcxx-abspath.cpp @@ -1,15 +1,20 @@ -// Clang on MacOS can find libc++ living beside the installed compiler. -// This test makes sure our libTooling-based tools emulate this properly. +// Clang on MacOS can find libc++ living beside the installed compiler if there +// are no headers in the sysroot. This test makes sure our libTooling-based tools +// emulate this properly. // // RUN: rm -rf %t // RUN: mkdir %t // -// Install the mock libc++ (simulates the libc++ directory structure). -// RUN: cp -r %S/Inputs/mock-libcxx %t/ +// Install a mock toolchain root that contains a simulation of libc++. +// RUN: cp -r %S/Inputs/mock-toolchain-root %t/mock-toolchain-root // -// Pretend clang is installed beside the mock library that we provided. -// RUN: echo '[{"directory":"%t","command":"%t/mock-libcxx/bin/clang++ -stdlib=libc++ -target x86_64-apple-darwin -c test.cpp","file":"test.cpp"}]' | sed -e 's/\\/\//g' > %t/compile_commands.json +// Install a mock sysroot that doesn't contain anything, to make sure we +// prefer the libc++ headers in the toolchain. +// RUN: cp -r %S/Inputs/empty-sysroot %t/empty-sysroot +// +// RUN: echo '[{"directory":"%t","command":"%t/mock-toolchain-root/bin/clang -isysroot %t/empty-sysroot -stdlib=libc++ -target x86_64-apple-darwin -c test.cpp","file":"test.cpp"}]' | sed -e 's/\\/\//g' > %t/compile_commands.json // RUN: cp "%s" "%t/test.cpp" +// // clang-check will produce an error code if the mock library is not found. // RUN: clang-check -p "%t" "%t/test.cpp" diff --git a/clang/test/Tooling/clang-check-mac-libcxx-fixed-compilation-db.cpp b/clang/test/Tooling/clang-check-mac-libcxx-fixed-compilation-db.cpp --- a/clang/test/Tooling/clang-check-mac-libcxx-fixed-compilation-db.cpp +++ b/clang/test/Tooling/clang-check-mac-libcxx-fixed-compilation-db.cpp @@ -1,18 +1,23 @@ -// Clang on MacOS can find libc++ living beside the installed compiler. -// This test makes sure our libTooling-based tools emulate this properly with -// fixed compilation database. +// Clang on MacOS can find libc++ living beside the installed compiler if there +// are no headers in the sysroot. This test makes sure our libTooling-based tools +// emulate this properly with a fixed compilation database. // // RUN: rm -rf %t // RUN: mkdir %t // -// Install the mock libc++ (simulates the libc++ directory structure). -// RUN: cp -r %S/Inputs/mock-libcxx %t/ +// Install a mock toolchain root that contains a simulation of libc++. +// RUN: cp -r %S/Inputs/mock-toolchain-root %t/mock-toolchain-root // -// RUN: cp clang-check %t/mock-libcxx/bin/ +// Install a mock sysroot that doesn't contain anything, to make sure we +// prefer the libc++ headers in the toolchain. +// RUN: cp -r %S/Inputs/empty-sysroot %t/empty-sysroot +// +// RUN: cp clang-check %t/mock-toolchain-root/bin/ // RUN: cp %s %t/test.cpp -// RUN: "%t/mock-libcxx/bin/clang-check" -p %t %t/test.cpp -- \ +// RUN: "%t/mock-toolchain-root/bin/clang-check" -p %t %t/test.cpp -- \ // RUN: -stdlib=libc++ -target x86_64-apple-darwin \ -// RUN: -ccc-install-dir %t/mock-libcxx/bin +// RUN: -isysroot %t/empty-sysroot \ +// RUN: -ccc-install-dir %t/mock-toolchain-root/bin // // ^ -ccc-install-dir passed to unbreak tests on *BSD where // getMainExecutable() relies on real argv[0] being passed diff --git a/clang/test/Tooling/clang-check-mac-libcxx-relpath.cpp b/clang/test/Tooling/clang-check-mac-libcxx-relpath.cpp --- a/clang/test/Tooling/clang-check-mac-libcxx-relpath.cpp +++ b/clang/test/Tooling/clang-check-mac-libcxx-relpath.cpp @@ -1,15 +1,20 @@ -// Clang on MacOS can find libc++ living beside the installed compiler. -// This test makes sure our libTooling-based tools emulate this properly. +// Clang on MacOS can find libc++ living beside the installed compiler if there +// are no headers in the sysroot. This test makes sure our libTooling-based tools +// emulate this properly. // // RUN: rm -rf %t // RUN: mkdir %t // -// Install the mock libc++ (simulates the libc++ directory structure). -// RUN: cp -r %S/Inputs/mock-libcxx %t/ +// Install a mock toolchain root that contains a simulation of libc++. +// RUN: cp -r %S/Inputs/mock-toolchain-root %t/mock-toolchain-root // -// Pretend clang is installed beside the mock library that we provided. -// RUN: echo '[{"directory":"%t","command":"mock-libcxx/bin/clang++ -stdlib=libc++ -target x86_64-apple-darwin -c test.cpp","file":"test.cpp"}]' | sed -e 's/\\/\//g' > %t/compile_commands.json +// Install a mock sysroot that doesn't contain anything, to make sure we +// prefer the libc++ headers in the toolchain. +// RUN: cp -r %S/Inputs/empty-sysroot %t/empty-sysroot +// +// RUN: echo '[{"directory":"%t","command":"mock-toolchain-root/bin/clang -isysroot %t/empty-sysroot -stdlib=libc++ -target x86_64-apple-darwin -c test.cpp","file":"test.cpp"}]' | sed -e 's/\\/\//g' > %t/compile_commands.json // RUN: cp "%s" "%t/test.cpp" +// // clang-check will produce an error code if the mock library is not found. // RUN: clang-check -p "%t" "%t/test.cpp"