diff options
9 files changed, 49 insertions, 4 deletions
diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h index c61cf2a..f8329ae 100644 --- a/clang/include/clang/Driver/ToolChain.h +++ b/clang/include/clang/Driver/ToolChain.h @@ -738,6 +738,12 @@ public: // Whether to print a message if a checked directory isn't available. LLVM_PREFERRED_TYPE(bool) unsigned PrintDebugStatements : 1; + + private: + LLVM_PREFERRED_TYPE(bool) + unsigned CheckCxx03 : 1; + + friend class ToolChain; }; /// Helper function to implement AddClangCXXStdlibIncludeArgs for libc++. diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index 42c9d6e..1e94a53 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -1255,13 +1255,20 @@ bool ToolChain::AddLibcxxInclude(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, llvm::Twine IncludeRoot, IncludeStrategy Strategy) const { + using namespace std::literals; + SmallString<128> Path; IncludeRoot.toVector(Path); - auto VersionDirName = - Strategy.Availability == IncludeStrategy::UseMaxVersionAvailable - ? detectLibcxxVersion(Path) - : "v1"; + auto VersionDirName = [&] { + if (Strategy.CheckCxx03) + return "c++03"s; + + if (Strategy.Availability == IncludeStrategy::UseMaxVersionAvailable) + return detectLibcxxVersion(Path); + + return "v1"s; + }(); if (VersionDirName.empty()) return false; @@ -1274,6 +1281,20 @@ bool ToolChain::AddLibcxxInclude(const llvm::opt::ArgList &DriverArgs, addSystemInclude(DriverArgs, CC1Args, TargetDir); } + if (const Arg *A = + DriverArgs.getLastArg(options::OPT_std_EQ, options::OPT_ansi); + !Strategy.CheckCxx03 && + (A && (A->getOption().matches(options::OPT_ansi) || + A->getValue() == "c++98"sv || A->getValue() == "c++03"sv || + A->getValue() == "gnu++98"sv || A->getValue() == "gnu++03"sv))) { + auto StrategyCopy = Strategy; + StrategyCopy.AddTargetDirIfAvailable = false; + StrategyCopy.Availability = IncludeStrategy::CheckIfAvailable; + StrategyCopy.CheckCxx03 = true; + if (AddLibcxxInclude(DriverArgs, CC1Args, IncludeRoot, StrategyCopy)) + return true; + } + llvm::sys::path::append(Path, "c++", VersionDirName); if ((Strategy.Availability != IncludeStrategy::AssumeAvailable || diff --git a/clang/test/Driver/Inputs/basic_linux_libcxx_tree/usr/include/c++/c++03/.keep b/clang/test/Driver/Inputs/basic_linux_libcxx_tree/usr/include/c++/c++03/.keep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/clang/test/Driver/Inputs/basic_linux_libcxx_tree/usr/include/c++/c++03/.keep diff --git a/clang/test/Driver/Inputs/basic_linux_libcxx_tree_no_cxx03/usr/bin/.keep b/clang/test/Driver/Inputs/basic_linux_libcxx_tree_no_cxx03/usr/bin/.keep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/clang/test/Driver/Inputs/basic_linux_libcxx_tree_no_cxx03/usr/bin/.keep diff --git a/clang/test/Driver/Inputs/basic_linux_libcxx_tree_no_cxx03/usr/include/c++/v1/.keep b/clang/test/Driver/Inputs/basic_linux_libcxx_tree_no_cxx03/usr/include/c++/v1/.keep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/clang/test/Driver/Inputs/basic_linux_libcxx_tree_no_cxx03/usr/include/c++/v1/.keep diff --git a/clang/test/Driver/Inputs/basic_linux_libcxx_tree_no_cxx03/usr/include/x86_64-unknown-linux-gnu/c++/v1/.keep b/clang/test/Driver/Inputs/basic_linux_libcxx_tree_no_cxx03/usr/include/x86_64-unknown-linux-gnu/c++/v1/.keep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/clang/test/Driver/Inputs/basic_linux_libcxx_tree_no_cxx03/usr/include/x86_64-unknown-linux-gnu/c++/v1/.keep diff --git a/clang/test/Driver/Inputs/basic_linux_libcxx_tree_no_cxx03/usr/lib/.keep b/clang/test/Driver/Inputs/basic_linux_libcxx_tree_no_cxx03/usr/lib/.keep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/clang/test/Driver/Inputs/basic_linux_libcxx_tree_no_cxx03/usr/lib/.keep diff --git a/clang/test/Driver/Inputs/basic_linux_libcxx_tree_no_cxx03/usr/lib/x86_64-unknown-linux-gnu/.keep b/clang/test/Driver/Inputs/basic_linux_libcxx_tree_no_cxx03/usr/lib/x86_64-unknown-linux-gnu/.keep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/clang/test/Driver/Inputs/basic_linux_libcxx_tree_no_cxx03/usr/lib/x86_64-unknown-linux-gnu/.keep diff --git a/clang/test/Driver/linux-header-search.cpp b/clang/test/Driver/linux-header-search.cpp index dd4d6eb48..0cce3e9 100644 --- a/clang/test/Driver/linux-header-search.cpp +++ b/clang/test/Driver/linux-header-search.cpp @@ -1,6 +1,24 @@ // General tests that the header search paths detected by the driver and passed // to CC1 are sane. // + +// Test a simulated installation of libc++ in C++03 mode on Linux, both through sysroot and +// the installation path of Clang. +// RUN: %clang -### %s -fsyntax-only 2>&1 \ +// RUN: --target=x86_64-unknown-linux-gnu \ +// RUN: -stdlib=libc++ \ +// RUN: -std=c++03 \ +// RUN: -ccc-install-dir %S/Inputs/basic_linux_tree/usr/bin \ +// RUN: -resource-dir=%S/Inputs/resource_dir \ +// RUN: --sysroot=%S/Inputs/basic_linux_libcxx_tree \ +// RUN: --gcc-toolchain="" \ +// RUN: | FileCheck --check-prefix=CHECK-BASIC-LIBCXX-SYSROOT-CXX03 %s +// CHECK-BASIC-LIBCXX-SYSROOT-CXX03: "-cc1" +// CHECK-BASIC-LIBCXX-SYSROOT-CXX03: "-isysroot" "[[SYSROOT:[^"]+]]" +// CHECK-BASIC-LIBCXX-SYSROOT-CXX03: "-internal-isystem" "[[SYSROOT]][[SEP:/|\\\\]]usr[[SEP]]include[[SEP]]x86_64-unknown-linux-gnu[[SEP]]c++[[SEP]]v1" +// CHECK-BASIC-LIBCXX-SYSROOT-CXX03: "-internal-isystem" "[[SYSROOT]][[SEP]]usr[[SEP]]include[[SEP]]c++[[SEP]]c++03" +// CHECK-BASIC-LIBCXX-SYSROOT-CXX03: "-internal-isystem" "[[SYSROOT]]/usr/local/include" + // Test a simulated installation of libc++ on Linux, both through sysroot and // the installation path of Clang. // RUN: %clang -### %s -fsyntax-only 2>&1 \ |