[clang] users/philnik777/add libcxx03 include strategy (PR #83723)
Nikolas Klauser via cfe-commits
cfe-commits at lists.llvm.org
Sun Mar 3 04:49:03 PST 2024
https://github.com/philnik777 created https://github.com/llvm/llvm-project/pull/83723
- [Clang][Driver] Merge the different strategies of how libc++ is included
- [Clang][Driver] Add special-casing for including libc++ in C++03
>From 756f80f22744bb0f2bfb81e6c4010054f1279337 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Fri, 1 Mar 2024 20:49:30 +0100
Subject: [PATCH 1/2] [Clang][Driver] Merge the different strategies of how
libc++ is included
---
clang/include/clang/Driver/ToolChain.h | 41 ++++++++++++++++++++
clang/lib/Driver/ToolChain.cpp | 41 ++++++++++++++++++++
clang/lib/Driver/ToolChains/AIX.cpp | 10 ++---
clang/lib/Driver/ToolChains/BareMetal.cpp | 13 +++----
clang/lib/Driver/ToolChains/CrossWindows.cpp | 3 +-
clang/lib/Driver/ToolChains/Darwin.cpp | 32 ++++++---------
clang/lib/Driver/ToolChains/FreeBSD.cpp | 5 ++-
clang/lib/Driver/ToolChains/Fuchsia.cpp | 22 ++---------
clang/lib/Driver/ToolChains/Gnu.cpp | 6 +--
clang/lib/Driver/ToolChains/Haiku.cpp | 5 ++-
clang/lib/Driver/ToolChains/Hexagon.cpp | 27 ++++++++-----
clang/lib/Driver/ToolChains/MinGW.cpp | 16 +++-----
clang/lib/Driver/ToolChains/MipsLinux.cpp | 7 ++--
clang/lib/Driver/ToolChains/NaCl.cpp | 16 ++++----
clang/lib/Driver/ToolChains/NetBSD.cpp | 20 +++++-----
clang/lib/Driver/ToolChains/OHOS.cpp | 9 ++---
clang/lib/Driver/ToolChains/OpenBSD.cpp | 5 ++-
clang/lib/Driver/ToolChains/WebAssembly.cpp | 4 +-
clang/lib/Driver/ToolChains/ZOS.cpp | 22 ++++-------
clang/lib/Driver/ToolChains/ZOS.h | 3 --
20 files changed, 178 insertions(+), 129 deletions(-)
diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h
index fbe2e8fe8e88d8..c61cf2aa064ed5 100644
--- a/clang/include/clang/Driver/ToolChain.h
+++ b/clang/include/clang/Driver/ToolChain.h
@@ -705,6 +705,47 @@ class ToolChain {
AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const;
+ struct IncludeStrategy {
+ enum AvailabilityOptions {
+ // Check whether the directory is exists before adding it to the
+ // include path. This is the case if AssumeAvailable isn't set.
+ CheckIfAvailable,
+
+ // Don't check whether the directory exists. Just assume it does and add
+ // the include.
+ AssumeAvailable,
+
+ // Use v<MaxNumber> that is inside `<IncludeRoot>/c++`. If not set, always
+ // uses v1.
+ UseMaxVersionAvailable,
+ };
+
+ IncludeStrategy(AvailabilityOptions Availability,
+ bool AddTargetDirIfAvailable = false,
+ bool PrintDebugStatements = false)
+ : Availability(Availability),
+ AddTargetDirIfAvailable(AddTargetDirIfAvailable),
+ PrintDebugStatements(PrintDebugStatements) {}
+
+ LLVM_PREFERRED_TYPE(AvailabilityOptions)
+ unsigned Availability : 2;
+
+ // Check whether the directory `<IncludeRoot>/<target-triple>/c++/v<N>`
+ // exists, and add it to the include path if it does.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned AddTargetDirIfAvailable : 1;
+
+ // Whether to print a message if a checked directory isn't available.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned PrintDebugStatements : 1;
+ };
+
+ /// Helper function to implement AddClangCXXStdlibIncludeArgs for libc++.
+ bool AddLibcxxInclude(const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args,
+ llvm::Twine IncludeRoot,
+ IncludeStrategy Strategy) const;
+
/// AddClangCXXStdlibIsystemArgs - Add the clang -cc1 level arguments to set
/// the specified include paths for the C++ standard library.
void AddClangCXXStdlibIsystemArgs(const llvm::opt::ArgList &DriverArgs,
diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index 08b1fd01b3c0ac..42c9d6e91d3c35 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -40,6 +40,7 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/FileUtilities.h"
#include "llvm/Support/Path.h"
+#include "llvm/Support/WithColor.h"
#include "llvm/Support/VersionTuple.h"
#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/TargetParser/AArch64TargetParser.h"
@@ -1250,6 +1251,46 @@ void ToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
DriverArgs.AddAllArgs(CC1Args, options::OPT_stdlib_EQ);
}
+bool ToolChain::AddLibcxxInclude(const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args,
+ llvm::Twine IncludeRoot,
+ IncludeStrategy Strategy) const {
+ SmallString<128> Path;
+ IncludeRoot.toVector(Path);
+
+ auto VersionDirName =
+ Strategy.Availability == IncludeStrategy::UseMaxVersionAvailable
+ ? detectLibcxxVersion(Path)
+ : "v1";
+
+ if (VersionDirName.empty())
+ return false;
+
+ if (Strategy.AddTargetDirIfAvailable) {
+ SmallString<128> TargetDir(Path);
+ llvm::sys::path::append(TargetDir, getTripleString(), "c++",
+ VersionDirName);
+ if (getVFS().exists(TargetDir))
+ addSystemInclude(DriverArgs, CC1Args, TargetDir);
+ }
+
+ llvm::sys::path::append(Path, "c++", VersionDirName);
+
+ if ((Strategy.Availability != IncludeStrategy::AssumeAvailable ||
+ Strategy.PrintDebugStatements) &&
+ !D.getVFS().exists(Path)) {
+ if (Strategy.PrintDebugStatements)
+ WithColor::warning(errs(), "Clang")
+ << "ignoring nonexistent directory \"" << Path << "\"\n";
+
+ if (Strategy.Availability != IncludeStrategy::AssumeAvailable)
+ return false;
+ }
+
+ addSystemInclude(DriverArgs, CC1Args, Path.str());
+ return true;
+}
+
void ToolChain::AddClangCXXStdlibIsystemArgs(
const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const {
diff --git a/clang/lib/Driver/ToolChains/AIX.cpp b/clang/lib/Driver/ToolChains/AIX.cpp
index e6126ff62db3c9..017ab3182b1e46 100644
--- a/clang/lib/Driver/ToolChains/AIX.cpp
+++ b/clang/lib/Driver/ToolChains/AIX.cpp
@@ -404,11 +404,11 @@ void AIX::AddClangCXXStdlibIncludeArgs(
llvm::report_fatal_error(
"picking up libstdc++ headers is unimplemented on AIX");
case ToolChain::CST_Libcxx: {
- llvm::StringRef Sysroot = GetHeaderSysroot(DriverArgs);
- SmallString<128> PathCPP(Sysroot);
- llvm::sys::path::append(PathCPP, "opt/IBM/openxlCSDK", "include", "c++",
- "v1");
- addSystemInclude(DriverArgs, CC1Args, PathCPP.str());
+ llvm::SmallString<128> Path = GetHeaderSysroot(DriverArgs);
+ llvm::sys::path::append(Path, "opt/IBM/openxlCSDK/include");
+ ToolChain::AddLibcxxInclude(DriverArgs, CC1Args, Path,
+ IncludeStrategy::AssumeAvailable);
+
// Required in order to suppress conflicting C++ overloads in the system
// libc headers that were used by XL C++.
CC1Args.push_back("-D__LIBC_NO_CPP_MATH_OVERLOADS__");
diff --git a/clang/lib/Driver/ToolChains/BareMetal.cpp b/clang/lib/Driver/ToolChains/BareMetal.cpp
index d5fc1d5dd25a8b..3f4edb1e82e5f2 100644
--- a/clang/lib/Driver/ToolChains/BareMetal.cpp
+++ b/clang/lib/Driver/ToolChains/BareMetal.cpp
@@ -309,14 +309,13 @@ void BareMetal::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
case ToolChain::CST_Libcxx: {
// First check sysroot/usr/include/c++/v1 if it exists.
SmallString<128> TargetDir(Dir);
- llvm::sys::path::append(TargetDir, "usr", "include", "c++", "v1");
- if (D.getVFS().exists(TargetDir)) {
- addSystemInclude(DriverArgs, CC1Args, TargetDir.str());
- break;
+ llvm::sys::path::append(TargetDir, "usr", "include");
+ if (!ToolChain::AddLibcxxInclude(DriverArgs, CC1Args, TargetDir.str(),
+ IncludeStrategy::CheckIfAvailable)) {
+ llvm::sys::path::append(Dir, "include");
+ ToolChain::AddLibcxxInclude(DriverArgs, CC1Args, Dir.str(),
+ IncludeStrategy::AssumeAvailable);
}
- // Add generic path if nothing else succeeded so far.
- llvm::sys::path::append(Dir, "include", "c++", "v1");
- addSystemInclude(DriverArgs, CC1Args, Dir.str());
break;
}
case ToolChain::CST_Libstdcxx: {
diff --git a/clang/lib/Driver/ToolChains/CrossWindows.cpp b/clang/lib/Driver/ToolChains/CrossWindows.cpp
index 3c5dfba329cf8e..df8b7cbd253fc3 100644
--- a/clang/lib/Driver/ToolChains/CrossWindows.cpp
+++ b/clang/lib/Driver/ToolChains/CrossWindows.cpp
@@ -269,7 +269,8 @@ AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs,
return;
if (GetCXXStdlibType(DriverArgs) == ToolChain::CST_Libcxx)
- addSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include/c++/v1");
+ ToolChain::AddLibcxxInclude(DriverArgs, CC1Args, SysRoot + "/usr/include",
+ IncludeStrategy::AssumeAvailable);
}
void CrossWindowsToolChain::
diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp
index cc1219d69d9910..6eb72b705a2da0 100644
--- a/clang/lib/Driver/ToolChains/Darwin.cpp
+++ b/clang/lib/Driver/ToolChains/Darwin.cpp
@@ -2536,38 +2536,28 @@ void DarwinClang::AddClangCXXStdlibIncludeArgs(
// parent_path.
llvm::SmallString<128> InstallBin =
llvm::StringRef(getDriver().getInstalledDir()); // <install>/bin
- llvm::sys::path::append(InstallBin, "..", "include", "c++", "v1");
- if (getVFS().exists(InstallBin)) {
- addSystemInclude(DriverArgs, CC1Args, InstallBin);
+ llvm::sys::path::append(InstallBin, "..", "include");
+ IncludeStrategy Strategy = IncludeStrategy::CheckIfAvailable;
+ Strategy.PrintDebugStatements = DriverArgs.hasArg(options::OPT_v);
+ if (ToolChain::AddLibcxxInclude(DriverArgs, CC1Args, InstallBin.str(),
+ Strategy))
return;
- } else if (DriverArgs.hasArg(options::OPT_v)) {
- llvm::errs() << "ignoring nonexistent directory \"" << InstallBin
- << "\"\n";
- }
// (2) Check for the folder where the executable is located, if different.
if (getDriver().getInstalledDir() != getDriver().Dir) {
InstallBin = llvm::StringRef(getDriver().Dir);
- llvm::sys::path::append(InstallBin, "..", "include", "c++", "v1");
- if (getVFS().exists(InstallBin)) {
- addSystemInclude(DriverArgs, CC1Args, InstallBin);
+ llvm::sys::path::append(InstallBin, "..", "include");
+ if (ToolChain::AddLibcxxInclude(DriverArgs, CC1Args, InstallBin.str(),
+ Strategy))
return;
- } else if (DriverArgs.hasArg(options::OPT_v)) {
- llvm::errs() << "ignoring nonexistent directory \"" << InstallBin
- << "\"\n";
- }
}
// Otherwise, check for (3)
llvm::SmallString<128> SysrootUsr = Sysroot;
- llvm::sys::path::append(SysrootUsr, "usr", "include", "c++", "v1");
- if (getVFS().exists(SysrootUsr)) {
- addSystemInclude(DriverArgs, CC1Args, SysrootUsr);
+ llvm::sys::path::append(SysrootUsr, "usr", "include");
+ if (ToolChain::AddLibcxxInclude(DriverArgs, CC1Args, SysrootUsr.str(),
+ Strategy))
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/lib/Driver/ToolChains/FreeBSD.cpp b/clang/lib/Driver/ToolChains/FreeBSD.cpp
index b7c9e0e51cdb66..66ff56ccbf5398 100644
--- a/clang/lib/Driver/ToolChains/FreeBSD.cpp
+++ b/clang/lib/Driver/ToolChains/FreeBSD.cpp
@@ -436,8 +436,9 @@ void FreeBSD::AddClangSystemIncludeArgs(
void FreeBSD::addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const {
- addSystemInclude(DriverArgs, CC1Args,
- concat(getDriver().SysRoot, "/usr/include/c++/v1"));
+ AddLibcxxInclude(DriverArgs, CC1Args,
+ concat(getDriver().SysRoot, "/usr/include"),
+ IncludeStrategy::AssumeAvailable);
}
void FreeBSD::AddCXXStdlibLibArgs(const ArgList &Args,
diff --git a/clang/lib/Driver/ToolChains/Fuchsia.cpp b/clang/lib/Driver/ToolChains/Fuchsia.cpp
index 14b838500becce..4b04062b0923ac 100644
--- a/clang/lib/Driver/ToolChains/Fuchsia.cpp
+++ b/clang/lib/Driver/ToolChains/Fuchsia.cpp
@@ -425,30 +425,14 @@ void Fuchsia::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
return;
const Driver &D = getDriver();
- std::string Target = getTripleString();
-
- auto AddCXXIncludePath = [&](StringRef Path) {
- std::string Version = detectLibcxxVersion(Path);
- if (Version.empty())
- return;
-
- // First add the per-target include path.
- SmallString<128> TargetDir(Path);
- llvm::sys::path::append(TargetDir, Target, "c++", Version);
- if (getVFS().exists(TargetDir))
- addSystemInclude(DriverArgs, CC1Args, TargetDir);
-
- // Second add the generic one.
- SmallString<128> Dir(Path);
- llvm::sys::path::append(Dir, "c++", Version);
- addSystemInclude(DriverArgs, CC1Args, Dir);
- };
switch (GetCXXStdlibType(DriverArgs)) {
case ToolChain::CST_Libcxx: {
SmallString<128> P(D.Dir);
llvm::sys::path::append(P, "..", "include");
- AddCXXIncludePath(P);
+ AddLibcxxInclude(
+ DriverArgs, CC1Args, P,
+ IncludeStrategy{IncludeStrategy::UseMaxVersionAvailable, true});
break;
}
diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp
index a2526a2b903964..4e867624e8ef5d 100644
--- a/clang/lib/Driver/ToolChains/Gnu.cpp
+++ b/clang/lib/Driver/ToolChains/Gnu.cpp
@@ -3284,6 +3284,7 @@ Generic_GCC::addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
if (Version.empty())
return false;
+ // FIXME: This should be part of AddLibcxxInclude
// First add the per-target include path if it exists.
bool TargetDirExists = false;
std::optional<std::string> TargetIncludeDir = getTargetSubDirPath(Path);
@@ -3299,9 +3300,8 @@ Generic_GCC::addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
return false;
// Second add the generic one.
- SmallString<128> GenericDir(Path);
- llvm::sys::path::append(GenericDir, "c++", Version);
- addSystemInclude(DriverArgs, CC1Args, GenericDir);
+ ToolChain::AddLibcxxInclude(DriverArgs, CC1Args, Path,
+ IncludeStrategy::UseMaxVersionAvailable);
return true;
};
diff --git a/clang/lib/Driver/ToolChains/Haiku.cpp b/clang/lib/Driver/ToolChains/Haiku.cpp
index e0d94035823fd3..5cd83b92eb9139 100644
--- a/clang/lib/Driver/ToolChains/Haiku.cpp
+++ b/clang/lib/Driver/ToolChains/Haiku.cpp
@@ -270,8 +270,9 @@ void Haiku::AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
void Haiku::addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const {
- addSystemInclude(DriverArgs, CC1Args,
- concat(getDriver().SysRoot, "/boot/system/develop/headers/c++/v1"));
+ AddLibcxxInclude(DriverArgs, CC1Args,
+ concat(getDriver().SysRoot, "/boot/system/develop/headers"),
+ IncludeStrategy::AssumeAvailable);
}
Tool *Haiku::buildLinker() const { return new tools::haiku::Linker(*this); }
diff --git a/clang/lib/Driver/ToolChains/Hexagon.cpp b/clang/lib/Driver/ToolChains/Hexagon.cpp
index fa47c98901e145..7358c2a12132ca 100644
--- a/clang/lib/Driver/ToolChains/Hexagon.cpp
+++ b/clang/lib/Driver/ToolChains/Hexagon.cpp
@@ -737,18 +737,27 @@ void HexagonToolChain::addLibCxxIncludePaths(
const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const {
const Driver &D = getDriver();
- if (!D.SysRoot.empty() && getTriple().isMusl())
- addLibStdCXXIncludePaths(D.SysRoot + "/usr/include/c++/v1", "", "",
- DriverArgs, CC1Args);
- else if (getTriple().isMusl())
- addLibStdCXXIncludePaths("/usr/include/c++/v1", "", "", DriverArgs,
- CC1Args);
- else {
+ if (!D.SysRoot.empty() && getTriple().isMusl()) {
+ ToolChain::AddLibcxxInclude(DriverArgs, CC1Args, D.SysRoot + "/usr/include",
+ IncludeStrategy::AssumeAvailable);
+ // FIXME: Is this actually expected? (Same below)
+ addSystemInclude(DriverArgs, CC1Args,
+ D.SysRoot + "/usr/include/c++/v1/backward");
+ }
+ else if (getTriple().isMusl()) {
+ ToolChain::AddLibcxxInclude(DriverArgs, CC1Args, "/usr/include",
+ IncludeStrategy::AssumeAvailable);
+ addSystemInclude(DriverArgs, CC1Args, "/usr/include/c++/v1/backward");
+ } else {
std::string TargetDir = getHexagonTargetDir(D.InstalledDir, D.PrefixDirs);
- addLibStdCXXIncludePaths(TargetDir + "/hexagon/include/c++/v1", "", "",
- DriverArgs, CC1Args);
+ ToolChain::AddLibcxxInclude(DriverArgs, CC1Args,
+ TargetDir + "/hexagon/include",
+ IncludeStrategy::AssumeAvailable);
+ addSystemInclude(DriverArgs, CC1Args,
+ TargetDir + "/hexagon/include/c++/v1/backward");
}
}
+
void HexagonToolChain::addLibStdCxxIncludePaths(
const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const {
diff --git a/clang/lib/Driver/ToolChains/MinGW.cpp b/clang/lib/Driver/ToolChains/MinGW.cpp
index 2b7fc104ea95aa..d13c5b736ab02e 100644
--- a/clang/lib/Driver/ToolChains/MinGW.cpp
+++ b/clang/lib/Driver/ToolChains/MinGW.cpp
@@ -745,16 +745,12 @@ void toolchains::MinGW::AddClangCXXStdlibIncludeArgs(
switch (GetCXXStdlibType(DriverArgs)) {
case ToolChain::CST_Libcxx: {
- std::string TargetDir = (Base + "include" + Slash + getTripleString() +
- Slash + "c++" + Slash + "v1")
- .str();
- if (getDriver().getVFS().exists(TargetDir))
- addSystemInclude(DriverArgs, CC1Args, TargetDir);
- addSystemInclude(DriverArgs, CC1Args,
- Base + SubdirName + Slash + "include" + Slash + "c++" +
- Slash + "v1");
- addSystemInclude(DriverArgs, CC1Args,
- Base + "include" + Slash + "c++" + Slash + "v1");
+ ToolChain::AddLibcxxInclude(
+ DriverArgs, CC1Args, Base + "include",
+ IncludeStrategy{IncludeStrategy::AssumeAvailable, true});
+ ToolChain::AddLibcxxInclude(DriverArgs, CC1Args,
+ Base + SubdirName + Slash + "include",
+ IncludeStrategy::AssumeAvailable);
break;
}
diff --git a/clang/lib/Driver/ToolChains/MipsLinux.cpp b/clang/lib/Driver/ToolChains/MipsLinux.cpp
index 4183eccceedb4e..1ea85c402ca28e 100644
--- a/clang/lib/Driver/ToolChains/MipsLinux.cpp
+++ b/clang/lib/Driver/ToolChains/MipsLinux.cpp
@@ -97,11 +97,10 @@ void MipsLLVMToolChain::addLibCxxIncludePaths(
llvm::opt::ArgStringList &CC1Args) const {
if (const auto &Callback = Multilibs.includeDirsCallback()) {
for (std::string Path : Callback(SelectedMultilibs.back())) {
- Path = getDriver().getInstalledDir() + Path + "/c++/v1";
- if (llvm::sys::fs::exists(Path)) {
- addSystemInclude(DriverArgs, CC1Args, Path);
+ if (ToolChain::AddLibcxxInclude(DriverArgs, CC1Args,
+ getDriver().getInstalledDir() + Path,
+ IncludeStrategy::CheckIfAvailable))
return;
- }
}
}
}
diff --git a/clang/lib/Driver/ToolChains/NaCl.cpp b/clang/lib/Driver/ToolChains/NaCl.cpp
index 22f038e5152ff2..57cd3cf29d9122 100644
--- a/clang/lib/Driver/ToolChains/NaCl.cpp
+++ b/clang/lib/Driver/ToolChains/NaCl.cpp
@@ -317,24 +317,22 @@ void NaClToolChain::addLibCxxIncludePaths(
SmallString<128> P(D.Dir + "/../");
switch (getTriple().getArch()) {
default:
- break;
+ return;
case llvm::Triple::arm:
- llvm::sys::path::append(P, "arm-nacl/include/c++/v1");
- addSystemInclude(DriverArgs, CC1Args, P.str());
+ llvm::sys::path::append(P, "arm-nacl/include");
break;
case llvm::Triple::x86:
- llvm::sys::path::append(P, "x86_64-nacl/include/c++/v1");
- addSystemInclude(DriverArgs, CC1Args, P.str());
+ llvm::sys::path::append(P, "x86_64-nacl/include");
break;
case llvm::Triple::x86_64:
- llvm::sys::path::append(P, "x86_64-nacl/include/c++/v1");
- addSystemInclude(DriverArgs, CC1Args, P.str());
+ llvm::sys::path::append(P, "x86_64-nacl/include");
break;
case llvm::Triple::mipsel:
- llvm::sys::path::append(P, "mipsel-nacl/include/c++/v1");
- addSystemInclude(DriverArgs, CC1Args, P.str());
+ llvm::sys::path::append(P, "mipsel-nacl/include");
break;
}
+ ToolChain::AddLibcxxInclude(DriverArgs, CC1Args, P,
+ IncludeStrategy::AssumeAvailable);
}
ToolChain::CXXStdlibType
diff --git a/clang/lib/Driver/ToolChains/NetBSD.cpp b/clang/lib/Driver/ToolChains/NetBSD.cpp
index 240bf5764b9cce..f6ccde40b06520 100644
--- a/clang/lib/Driver/ToolChains/NetBSD.cpp
+++ b/clang/lib/Driver/ToolChains/NetBSD.cpp
@@ -495,21 +495,21 @@ void NetBSD::addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const {
const std::string Candidates[] = {
// directory relative to build tree
- concat(getDriver().Dir, "/../include/c++/v1"),
+ concat(getDriver().Dir, "/../include"),
// system install with full upstream path
- concat(getDriver().SysRoot, "/usr/include/c++/v1"),
- // system install from src
- concat(getDriver().SysRoot, "/usr/include/c++"),
+ concat(getDriver().SysRoot, "/usr/include"),
};
for (const auto &IncludePath : Candidates) {
- if (!getVFS().exists(IncludePath + "/__config"))
- continue;
-
- // Use the first candidate that looks valid.
- addSystemInclude(DriverArgs, CC1Args, IncludePath);
- return;
+ if (ToolChain::AddLibcxxInclude(DriverArgs, CC1Args, IncludePath,
+ IncludeStrategy::CheckIfAvailable))
+ return;
}
+
+ // system install from src
+ auto NonV1Path = concat(getDriver().SysRoot, "/usr/include/c++");
+ if (getVFS().exists(NonV1Path))
+ addSystemInclude(DriverArgs, CC1Args, NonV1Path);
}
void NetBSD::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
diff --git a/clang/lib/Driver/ToolChains/OHOS.cpp b/clang/lib/Driver/ToolChains/OHOS.cpp
index 1e50c9d71d59cc..81d66ce492a306 100644
--- a/clang/lib/Driver/ToolChains/OHOS.cpp
+++ b/clang/lib/Driver/ToolChains/OHOS.cpp
@@ -242,12 +242,9 @@ void OHOS::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
switch (GetCXXStdlibType(DriverArgs)) {
case ToolChain::CST_Libcxx: {
std::string IncPath = makePath({getDriver().Dir, "..", "include"});
- std::string IncTargetPath =
- makePath({IncPath, getMultiarchTriple(getTriple()), "c++", "v1"});
- if (getVFS().exists(IncTargetPath)) {
- addSystemInclude(DriverArgs, CC1Args, makePath({IncPath, "c++", "v1"}));
- addSystemInclude(DriverArgs, CC1Args, IncTargetPath);
- }
+ ToolChain::AddLibcxxInclude(
+ DriverArgs, CC1Args, IncPath,
+ IncludeStrategy{IncludeStrategy::CheckIfAvailable, true});
break;
}
diff --git a/clang/lib/Driver/ToolChains/OpenBSD.cpp b/clang/lib/Driver/ToolChains/OpenBSD.cpp
index fd6aa4d7e68447..bbdd4f8849a453 100644
--- a/clang/lib/Driver/ToolChains/OpenBSD.cpp
+++ b/clang/lib/Driver/ToolChains/OpenBSD.cpp
@@ -351,8 +351,9 @@ void OpenBSD::AddClangSystemIncludeArgs(
void OpenBSD::addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const {
- addSystemInclude(DriverArgs, CC1Args,
- concat(getDriver().SysRoot, "/usr/include/c++/v1"));
+ ToolChain::AddLibcxxInclude(DriverArgs, CC1Args,
+ concat(getDriver().SysRoot, "/usr/include"),
+ IncludeStrategy::AssumeAvailable);
}
void OpenBSD::AddCXXStdlibLibArgs(const ArgList &Args,
diff --git a/clang/lib/Driver/ToolChains/WebAssembly.cpp b/clang/lib/Driver/ToolChains/WebAssembly.cpp
index 57f4600727ec89..3b7bafaf9e93ae 100644
--- a/clang/lib/Driver/ToolChains/WebAssembly.cpp
+++ b/clang/lib/Driver/ToolChains/WebAssembly.cpp
@@ -507,6 +507,7 @@ void WebAssembly::addLibCxxIncludePaths(
if (Version.empty())
return;
+ // FIXME: This should be part of AddLibcxxInclude
// First add the per-target include path if the OS is known.
if (IsKnownOs) {
std::string TargetDir = LibPath + "/" + MultiarchTriple + "/c++/" + Version;
@@ -514,7 +515,8 @@ void WebAssembly::addLibCxxIncludePaths(
}
// Second add the generic one.
- addSystemInclude(DriverArgs, CC1Args, LibPath + "/c++/" + Version);
+ ToolChain::AddLibcxxInclude(DriverArgs, CC1Args, LibPath,
+ IncludeStrategy::UseMaxVersionAvailable);
}
void WebAssembly::addLibStdCXXIncludePaths(
diff --git a/clang/lib/Driver/ToolChains/ZOS.cpp b/clang/lib/Driver/ToolChains/ZOS.cpp
index 96dbf602e7c1fc..73292e3210b6b4 100644
--- a/clang/lib/Driver/ToolChains/ZOS.cpp
+++ b/clang/lib/Driver/ToolChains/ZOS.cpp
@@ -301,19 +301,6 @@ void ZOS::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
addSystemInclude(DriverArgs, CC1Args, "/usr/include");
}
-void ZOS::TryAddIncludeFromPath(llvm::SmallString<128> Path,
- const llvm::opt::ArgList &DriverArgs,
- llvm::opt::ArgStringList &CC1Args) const {
- if (!getVFS().exists(Path)) {
- if (DriverArgs.hasArg(options::OPT_v))
- WithColor::warning(errs(), "Clang")
- << "ignoring nonexistent directory \"" << Path << "\"\n";
- if (!DriverArgs.hasArg(options::OPT__HASH_HASH_HASH))
- return;
- }
- addSystemInclude(DriverArgs, CC1Args, Path);
-}
-
void ZOS::AddClangCXXStdlibIncludeArgs(
const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const {
@@ -327,8 +314,13 @@ void ZOS::AddClangCXXStdlibIncludeArgs(
// <install>/bin/../include/c++/v1
llvm::SmallString<128> InstallBin =
llvm::StringRef(getDriver().getInstalledDir());
- llvm::sys::path::append(InstallBin, "..", "include", "c++", "v1");
- TryAddIncludeFromPath(InstallBin, DriverArgs, CC1Args);
+ llvm::sys::path::append(InstallBin, "..", "include");
+ IncludeStrategy Strategy = DriverArgs.hasArg(options::OPT__HASH_HASH_HASH)
+ ? IncludeStrategy::AssumeAvailable
+ : IncludeStrategy::CheckIfAvailable;
+ Strategy.PrintDebugStatements = DriverArgs.hasArg(options::OPT_v);
+
+ ToolChain::AddLibcxxInclude(DriverArgs, CC1Args, InstallBin, Strategy);
break;
}
case ToolChain::CST_Libstdcxx:
diff --git a/clang/lib/Driver/ToolChains/ZOS.h b/clang/lib/Driver/ToolChains/ZOS.h
index 45204ba0a543c1..fb60171d33559b 100644
--- a/clang/lib/Driver/ToolChains/ZOS.h
+++ b/clang/lib/Driver/ToolChains/ZOS.h
@@ -61,9 +61,6 @@ class LLVM_LIBRARY_VISIBILITY ZOS : public ToolChain {
}
bool isPICDefaultForced() const override { return false; }
- void TryAddIncludeFromPath(llvm::SmallString<128> Path,
- const llvm::opt::ArgList &DriverArgs,
- llvm::opt::ArgStringList &CC1Args) const;
void
AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const override;
>From a4b3917ae30620d3dd4fdb6b0fd92f7563314145 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Sun, 3 Mar 2024 13:21:23 +0100
Subject: [PATCH 2/2] [Clang][Driver] Add special-casing for including libc++
in C++03
---
clang/include/clang/Driver/ToolChain.h | 6 ++++
clang/lib/Driver/ToolChain.cpp | 29 ++++++++++++++++---
.../usr/include/c++/c++03/.keep | 0
.../usr/bin/.keep | 0
.../usr/include/c++/v1/.keep | 0
.../x86_64-unknown-linux-gnu/c++/v1/.keep | 0
.../usr/lib/.keep | 0
.../usr/lib/x86_64-unknown-linux-gnu/.keep | 0
clang/test/Driver/linux-header-search.cpp | 18 ++++++++++++
9 files changed, 49 insertions(+), 4 deletions(-)
create mode 100644 clang/test/Driver/Inputs/basic_linux_libcxx_tree/usr/include/c++/c++03/.keep
create mode 100644 clang/test/Driver/Inputs/basic_linux_libcxx_tree_no_cxx03/usr/bin/.keep
create mode 100644 clang/test/Driver/Inputs/basic_linux_libcxx_tree_no_cxx03/usr/include/c++/v1/.keep
create mode 100644 clang/test/Driver/Inputs/basic_linux_libcxx_tree_no_cxx03/usr/include/x86_64-unknown-linux-gnu/c++/v1/.keep
create mode 100644 clang/test/Driver/Inputs/basic_linux_libcxx_tree_no_cxx03/usr/lib/.keep
create mode 100644 clang/test/Driver/Inputs/basic_linux_libcxx_tree_no_cxx03/usr/lib/x86_64-unknown-linux-gnu/.keep
diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h
index c61cf2aa064ed5..f8329ae3fc39dd 100644
--- a/clang/include/clang/Driver/ToolChain.h
+++ b/clang/include/clang/Driver/ToolChain.h
@@ -738,6 +738,12 @@ class ToolChain {
// 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 42c9d6e91d3c35..1e94a53f8a1d90 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 00000000000000..e69de29bb2d1d6
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 00000000000000..e69de29bb2d1d6
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 00000000000000..e69de29bb2d1d6
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 00000000000000..e69de29bb2d1d6
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 00000000000000..e69de29bb2d1d6
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 00000000000000..e69de29bb2d1d6
diff --git a/clang/test/Driver/linux-header-search.cpp b/clang/test/Driver/linux-header-search.cpp
index dd4d6eb483a3fb..0cce3e91e6654e 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 \
More information about the cfe-commits
mailing list