Revert "[Clang] Take libstdc++ into account during GCC detection" (#154368)

Reverts llvm/llvm-project#145056
This commit is contained in:
Frederik Harwath 2025-08-19 18:35:58 +02:00 committed by GitHub
parent e04fedadba
commit f1e56ac032
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
37 changed files with 125 additions and 338 deletions

View File

@ -37,22 +37,6 @@ latest release, please see the `Clang Web Site <https://clang.llvm.org>`_ or the
Potentially Breaking Changes
============================
- Clang will now emit a warning if the auto-detected GCC installation
directory (i.e. the one with the largest version number) does not
contain libstdc++ include directories although a "complete" GCC
installation directory containing the include directories is
available. It is planned to change the auto-detection to prefer the
"complete" directory in the future. The warning will disappear if
the libstdc++ include directories are either installed or removed
for all GCC installation directories considered by the
auto-detection; see the output of ``clang -v`` for a list of those
directories. If the GCC installations cannot be modified and
maintaining the current choice of the auto-detection is desired, the
GCC installation directory can be selected explicitly using the
``--gcc-install-dir`` command line argument. This will silence the
warning. It can also be disabled using the
``-Wno-gcc-install-dir-libstdcxx`` command line flag.
C/C++ Language Potentially Breaking Changes
-------------------------------------------

View File

@ -885,9 +885,4 @@ def warn_drv_openacc_without_cir
: Warning<"OpenACC directives will result in no runtime behavior; use "
"-fclangir to enable runtime effect">,
InGroup<SourceUsesOpenACC>;
def warn_drv_gcc_install_dir_libstdcxx : Warning<
"future releases of the clang compiler will prefer GCC installations "
"containing libstdc++ include directories; '%0' would be chosen over '%1'">,
InGroup<DiagGroup<"gcc-install-dir-libstdcxx">>;
}

View File

@ -224,6 +224,9 @@ protected:
static void addSystemFrameworkInclude(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args,
const Twine &Path);
static void addSystemInclude(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args,
const Twine &Path);
static void addExternCSystemInclude(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args,
const Twine &Path);
@ -243,9 +246,6 @@ protected:
///@}
public:
static void addSystemInclude(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args,
const Twine &Path);
virtual ~ToolChain();
// Accessors

View File

@ -1409,6 +1409,13 @@ void ToolChain::addSystemFrameworkInclude(const llvm::opt::ArgList &DriverArgs,
CC1Args.push_back(DriverArgs.MakeArgString(Path));
}
/// Utility function to add a system include directory to CC1 arguments.
void ToolChain::addSystemInclude(const ArgList &DriverArgs,
ArgStringList &CC1Args, const Twine &Path) {
CC1Args.push_back("-internal-isystem");
CC1Args.push_back(DriverArgs.MakeArgString(Path));
}
/// Utility function to add a system include directory with extern "C"
/// semantics to CC1 arguments.
///
@ -1431,14 +1438,6 @@ void ToolChain::addExternCSystemIncludeIfExists(const ArgList &DriverArgs,
addExternCSystemInclude(DriverArgs, CC1Args, Path);
}
/// Utility function to add a system include directory to CC1 arguments.
/*static*/ void ToolChain::addSystemInclude(const ArgList &DriverArgs,
ArgStringList &CC1Args,
const Twine &Path) {
CC1Args.push_back("-internal-isystem");
CC1Args.push_back(DriverArgs.MakeArgString(Path));
}
/// Utility function to add a list of system framework directories to CC1.
void ToolChain::addSystemFrameworkIncludes(const ArgList &DriverArgs,
ArgStringList &CC1Args,

View File

@ -2123,11 +2123,10 @@ void Generic_GCC::GCCInstallationDetector::init(
StringRef TripleText =
llvm::sys::path::filename(llvm::sys::path::parent_path(InstallDir));
SelectedInstallation.Version = GCCVersion::Parse(VersionText);
SelectedInstallation.GCCTriple.setTriple(TripleText);
SelectedInstallation.GCCInstallPath = std::string(InstallDir);
SelectedInstallation.GCCParentLibPath =
SelectedInstallation.GCCInstallPath + "/../../..";
Version = GCCVersion::Parse(VersionText);
GCCTriple.setTriple(TripleText);
GCCInstallPath = std::string(InstallDir);
GCCParentLibPath = GCCInstallPath + "/../../..";
IsValid = true;
}
return;
@ -2187,7 +2186,7 @@ void Generic_GCC::GCCInstallationDetector::init(
// Loop over the various components which exist and select the best GCC
// installation available. GCC installs are ranked by version number.
const GCCVersion VersionZero = GCCVersion::Parse("0.0.0");
SelectedInstallation.Version = VersionZero;
Version = VersionZero;
for (const std::string &Prefix : Prefixes) {
auto &VFS = D.getVFS();
if (!VFS.exists(Prefix))
@ -2215,7 +2214,7 @@ void Generic_GCC::GCCInstallationDetector::init(
}
// Skip other prefixes once a GCC installation is found.
if (SelectedInstallation.Version > VersionZero)
if (Version > VersionZero)
break;
}
}
@ -2224,17 +2223,14 @@ void Generic_GCC::GCCInstallationDetector::print(raw_ostream &OS) const {
for (const auto &InstallPath : CandidateGCCInstallPaths)
OS << "Found candidate GCC installation: " << InstallPath << "\n";
if (!SelectedInstallation.GCCInstallPath.empty())
OS << "Selected GCC installation: " << SelectedInstallation.GCCInstallPath
<< "\n";
if (!GCCInstallPath.empty())
OS << "Selected GCC installation: " << GCCInstallPath << "\n";
for (const auto &Multilib : Multilibs)
OS << "Candidate multilib: " << Multilib << "\n";
if (Multilibs.size() != 0 ||
!SelectedInstallation.SelectedMultilib.isDefault())
OS << "Selected multilib: " << SelectedInstallation.SelectedMultilib
<< "\n";
if (Multilibs.size() != 0 || !SelectedMultilib.isDefault())
OS << "Selected multilib: " << SelectedMultilib << "\n";
}
bool Generic_GCC::GCCInstallationDetector::getBiarchSibling(Multilib &M) const {
@ -2772,50 +2768,14 @@ bool Generic_GCC::GCCInstallationDetector::ScanGCCForMultilibs(
}
Multilibs = Detected.Multilibs;
SelectedInstallation.SelectedMultilib =
Detected.SelectedMultilibs.empty() ? Multilib()
SelectedMultilib = Detected.SelectedMultilibs.empty()
? Multilib()
: Detected.SelectedMultilibs.back();
BiarchSibling = Detected.BiarchSibling;
return true;
}
bool Generic_GCC::GCCInstallationDetector::SelectGCCInstallationDirectory(
const SmallVector<Generic_GCC::GCCInstallCandidate, 3> &Installations,
const ArgList &Args,
Generic_GCC::GCCInstallCandidate &SelectedInstallation) const {
if (Installations.empty())
return false;
SelectedInstallation =
*max_element(Installations, [](const auto &Max, const auto &I) {
return I.Version > Max.Version;
});
// FIXME Start selecting installation with libstdc++ in clang 22,
// using the current way of selecting the installation as a fallback
// only. For now, warn if the installation with libstdc++ differs
// from SelectedInstallation.
const GCCInstallCandidate *InstallWithIncludes = nullptr;
for (const auto &I : Installations) {
if ((!InstallWithIncludes || I.Version > InstallWithIncludes->Version) &&
GCCInstallationHasLibStdcxxIncludePaths(I, Args))
InstallWithIncludes = &I;
}
if (InstallWithIncludes && SelectedInstallation.GCCInstallPath !=
InstallWithIncludes->GCCInstallPath)
D.Diag(diag::warn_drv_gcc_install_dir_libstdcxx)
<< InstallWithIncludes->GCCInstallPath
<< SelectedInstallation.GCCInstallPath;
// TODO Warn if SelectedInstallation does not contain libstdc++ includes
// although compiler flags indicate that it is required (C++ compilation,
// libstdc++ not explicitly disabled).
return true;
}
void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple(
const llvm::Triple &TargetTriple, const ArgList &Args,
const std::string &LibDir, StringRef CandidateTriple,
@ -2845,7 +2805,6 @@ void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple(
TargetTriple.getVendor() == llvm::Triple::Freescale ||
TargetTriple.getVendor() == llvm::Triple::OpenEmbedded}};
SmallVector<GCCInstallCandidate, 3> Installations;
for (auto &Suffix : Suffixes) {
if (!Suffix.Active)
continue;
@ -2863,31 +2822,23 @@ void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple(
continue; // Saw this path before; no need to look at it again.
if (CandidateVersion.isOlderThan(4, 1, 1))
continue;
if (CandidateVersion <= SelectedInstallation.Version && IsValid)
if (CandidateVersion <= Version)
continue;
if (!ScanGCCForMultilibs(TargetTriple, Args, LI->path(),
NeedsBiarchSuffix))
continue;
GCCInstallCandidate Installation;
Installation.Version = CandidateVersion;
Installation.GCCTriple.setTriple(CandidateTriple);
Version = CandidateVersion;
GCCTriple.setTriple(CandidateTriple);
// FIXME: We hack together the directory name here instead of
// using LI to ensure stable path separators across Windows and
// Linux.
Installation.GCCInstallPath =
(LibDir + "/" + LibSuffix + "/" + VersionText).str();
Installation.GCCParentLibPath =
(Installation.GCCInstallPath + "/../" + Suffix.ReversePath).str();
Installation.SelectedMultilib = getMultilib();
Installations.push_back(Installation);
GCCInstallPath = (LibDir + "/" + LibSuffix + "/" + VersionText).str();
GCCParentLibPath = (GCCInstallPath + "/../" + Suffix.ReversePath).str();
IsValid = true;
}
}
IsValid |=
SelectGCCInstallationDirectory(Installations, Args, SelectedInstallation);
}
bool Generic_GCC::GCCInstallationDetector::ScanGentooConfigs(
@ -2965,12 +2916,10 @@ bool Generic_GCC::GCCInstallationDetector::ScanGentooGccConfig(
NeedsBiarchSuffix))
continue;
SelectedInstallation.Version =
GCCVersion::Parse(ActiveVersion.second);
SelectedInstallation.GCCInstallPath = GentooPath;
SelectedInstallation.GCCParentLibPath =
GentooPath + std::string("/../../..");
SelectedInstallation.GCCTriple.setTriple(ActiveVersion.first);
Version = GCCVersion::Parse(ActiveVersion.second);
GCCInstallPath = GentooPath;
GCCParentLibPath = GentooPath + std::string("/../../..");
GCCTriple.setTriple(ActiveVersion.first);
IsValid = true;
return true;
}
@ -3173,9 +3122,8 @@ void Generic_GCC::AddMultilibIncludeArgs(const ArgList &DriverArgs,
// gcc TOOL_INCLUDE_DIR.
const llvm::Triple &GCCTriple = GCCInstallation.getTriple();
std::string LibPath(GCCInstallation.getParentLibPath());
ToolChain::addSystemInclude(DriverArgs, CC1Args,
Twine(LibPath) + "/../" + GCCTriple.str() +
"/include");
addSystemInclude(DriverArgs, CC1Args,
Twine(LibPath) + "/../" + GCCTriple.str() + "/include");
const auto &Callback = Multilibs.includeDirsCallback();
if (Callback) {
@ -3262,14 +3210,12 @@ Generic_GCC::addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
return;
}
static bool addLibStdCXXIncludePaths(llvm::vfs::FileSystem &vfs,
Twine IncludeDir, StringRef Triple,
bool Generic_GCC::addLibStdCXXIncludePaths(Twine IncludeDir, StringRef Triple,
Twine IncludeSuffix,
const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args,
bool DetectDebian = false) {
if (!vfs.exists(IncludeDir))
bool DetectDebian) const {
if (!getVFS().exists(IncludeDir))
return false;
// Debian native gcc uses g++-multiarch-incdir.diff which uses
@ -3281,48 +3227,39 @@ static bool addLibStdCXXIncludePaths(llvm::vfs::FileSystem &vfs,
std::string Path =
(Include + "/" + Triple + Dir.substr(Include.size()) + IncludeSuffix)
.str();
if (DetectDebian && !vfs.exists(Path))
if (DetectDebian && !getVFS().exists(Path))
return false;
// GPLUSPLUS_INCLUDE_DIR
ToolChain::addSystemInclude(DriverArgs, CC1Args, IncludeDir);
addSystemInclude(DriverArgs, CC1Args, IncludeDir);
// GPLUSPLUS_TOOL_INCLUDE_DIR. If Triple is not empty, add a target-dependent
// include directory.
if (DetectDebian)
ToolChain::addSystemInclude(DriverArgs, CC1Args, Path);
addSystemInclude(DriverArgs, CC1Args, Path);
else if (!Triple.empty())
ToolChain::addSystemInclude(DriverArgs, CC1Args,
addSystemInclude(DriverArgs, CC1Args,
IncludeDir + "/" + Triple + IncludeSuffix);
// GPLUSPLUS_BACKWARD_INCLUDE_DIR
ToolChain::addSystemInclude(DriverArgs, CC1Args, IncludeDir + "/backward");
addSystemInclude(DriverArgs, CC1Args, IncludeDir + "/backward");
return true;
}
bool Generic_GCC::addLibStdCXXIncludePaths(Twine IncludeDir, StringRef Triple,
Twine IncludeSuffix,
const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args,
bool DetectDebian) const {
return ::addLibStdCXXIncludePaths(getVFS(), IncludeDir, Triple, IncludeSuffix,
DriverArgs, CC1Args, DetectDebian);
}
bool Generic_GCC::GCCInstallCandidate::addGCCLibStdCxxIncludePaths(
llvm::vfs::FileSystem &vfs, const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args, StringRef DebianMultiarch) const {
bool Generic_GCC::addGCCLibStdCxxIncludePaths(
const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args,
StringRef DebianMultiarch) const {
assert(GCCInstallation.isValid());
// By default, look for the C++ headers in an include directory adjacent to
// the lib directory of the GCC installation. Note that this is expect to be
// equivalent to '/usr/include/c++/X.Y' in almost all cases.
StringRef LibDir = getParentLibPath();
StringRef InstallDir = getInstallPath();
StringRef TripleStr = getTriple().str();
const Multilib &Multilib = getMultilib();
const GCCVersion &Version = getVersion();
StringRef LibDir = GCCInstallation.getParentLibPath();
StringRef InstallDir = GCCInstallation.getInstallPath();
StringRef TripleStr = GCCInstallation.getTriple().str();
const Multilib &Multilib = GCCInstallation.getMultilib();
const GCCVersion &Version = GCCInstallation.getVersion();
// Try /../$triple/include/c++/$version (gcc --print-multiarch is not empty).
if (::addLibStdCXXIncludePaths(
vfs,
if (addLibStdCXXIncludePaths(
LibDir.str() + "/../" + TripleStr + "/include/c++/" + Version.Text,
TripleStr, Multilib.includeSuffix(), DriverArgs, CC1Args))
return true;
@ -3330,24 +3267,22 @@ bool Generic_GCC::GCCInstallCandidate::addGCCLibStdCxxIncludePaths(
// Try /gcc/$triple/$version/include/c++/ (gcc --print-multiarch is not
// empty). Like above but for GCC built with
// --enable-version-specific-runtime-libs.
if (::addLibStdCXXIncludePaths(vfs,
LibDir.str() + "/gcc/" + TripleStr + "/" +
if (addLibStdCXXIncludePaths(LibDir.str() + "/gcc/" + TripleStr + "/" +
Version.Text + "/include/c++/",
TripleStr, Multilib.includeSuffix(),
DriverArgs, CC1Args))
TripleStr, Multilib.includeSuffix(), DriverArgs,
CC1Args))
return true;
// Detect Debian g++-multiarch-incdir.diff.
if (::addLibStdCXXIncludePaths(
vfs, LibDir.str() + "/../include/c++/" + Version.Text,
DebianMultiarch, Multilib.includeSuffix(), DriverArgs, CC1Args,
/*Debian=*/true))
if (addLibStdCXXIncludePaths(LibDir.str() + "/../include/c++/" + Version.Text,
DebianMultiarch, Multilib.includeSuffix(),
DriverArgs, CC1Args, /*Debian=*/true))
return true;
// Try /../include/c++/$version (gcc --print-multiarch is empty).
if (::addLibStdCXXIncludePaths(
vfs, LibDir.str() + "/../include/c++/" + Version.Text, TripleStr,
Multilib.includeSuffix(), DriverArgs, CC1Args))
if (addLibStdCXXIncludePaths(LibDir.str() + "/../include/c++/" + Version.Text,
TripleStr, Multilib.includeSuffix(), DriverArgs,
CC1Args))
return true;
// Otherwise, fall back on a bunch of options which don't use multiarch
@ -3362,50 +3297,20 @@ bool Generic_GCC::GCCInstallCandidate::addGCCLibStdCxxIncludePaths(
};
for (const auto &IncludePath : LibStdCXXIncludePathCandidates) {
if (::addLibStdCXXIncludePaths(vfs, IncludePath, TripleStr,
Multilib.includeSuffix(), DriverArgs,
CC1Args))
if (addLibStdCXXIncludePaths(IncludePath, TripleStr,
Multilib.includeSuffix(), DriverArgs, CC1Args))
return true;
}
return false;
}
bool Generic_GCC::GCCInstallationDetector::
GCCInstallationHasLibStdcxxIncludePaths(
const GCCInstallCandidate &GCCInstallation,
const llvm::opt::ArgList &DriverArgs) const {
StringRef DebianMultiarch =
TripleToDebianMultiarch(GCCInstallation.getTriple());
// The following function checks for libstdc++ include paths and
// adds them to the provided argument list. Here we just need the
// check.
llvm::opt::ArgStringList dummyCC1Args;
return GCCInstallation.addGCCLibStdCxxIncludePaths(
D.getVFS(), DriverArgs, dummyCC1Args, DebianMultiarch);
}
bool Generic_GCC::addGCCLibStdCxxIncludePaths(
const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const {
assert(GCCInstallation.isValid());
// Detect Debian g++-multiarch-incdir.diff.
StringRef DebianMultiarch =
GCCInstallation.TripleToDebianMultiarch(GCCInstallation.getTriple());
return GCCInstallation.getSelectedInstallation().addGCCLibStdCxxIncludePaths(
getVFS(), DriverArgs, CC1Args, DebianMultiarch);
}
void
Generic_GCC::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const {
if (!GCCInstallation.isValid())
return;
GCCInstallation.getSelectedInstallation().addGCCLibStdCxxIncludePaths(
getVFS(), DriverArgs, CC1Args, GCCInstallation.getTriple().str());
if (GCCInstallation.isValid()) {
addGCCLibStdCxxIncludePaths(DriverArgs, CC1Args,
GCCInstallation.getTriple().str());
}
}
llvm::opt::DerivedArgList *

View File

@ -184,18 +184,46 @@ public:
bool operator>=(const GCCVersion &RHS) const { return !(*this < RHS); }
};
struct GCCInstallCandidate {
/// This is a class to find a viable GCC installation for Clang to
/// use.
///
/// This class tries to find a GCC installation on the system, and report
/// information about it. It starts from the host information provided to the
/// Driver, and has logic for fuzzing that where appropriate.
class GCCInstallationDetector {
bool IsValid;
llvm::Triple GCCTriple;
const Driver &D;
// FIXME: These might be better as path objects.
std::string GCCInstallPath;
std::string GCCParentLibPath;
llvm::Triple GCCTriple;
/// The primary multilib appropriate for the given flags.
Multilib SelectedMultilib;
/// On Biarch systems, this corresponds to the default multilib when
/// targeting the non-default multilib. Otherwise, it is empty.
std::optional<Multilib> BiarchSibling;
GCCVersion Version;
// We retain the list of install paths that were considered and rejected in
// order to print out detailed information in verbose mode.
std::set<std::string> CandidateGCCInstallPaths;
/// The set of multilibs that the detected installation supports.
MultilibSet Multilibs;
// Gentoo-specific toolchain configurations are stored here.
const std::string GentooConfigDir = "/etc/env.d/gcc";
public:
explicit GCCInstallationDetector(const Driver &D) : IsValid(false), D(D) {}
void init(const llvm::Triple &TargetTriple, const llvm::opt::ArgList &Args);
/// Check whether we detected a valid GCC install.
bool isValid() const { return IsValid; }
/// Get the GCC triple for the detected install.
const llvm::Triple &getTriple() const { return GCCTriple; }
@ -208,88 +236,6 @@ public:
/// Get the detected Multilib
const Multilib &getMultilib() const { return SelectedMultilib; }
/// Get the detected GCC version string.
const GCCVersion &getVersion() const { return Version; }
bool addGCCLibStdCxxIncludePaths(llvm::vfs::FileSystem &vfs,
const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args,
StringRef DebianMultiarch) const;
};
/// This is a class to find a viable GCC installation for Clang to
/// use.
///
/// This class tries to find a GCC installation on the system, and report
/// information about it. It starts from the host information provided to the
/// Driver, and has logic for fuzzing that where appropriate.
class GCCInstallationDetector {
bool IsValid;
const Driver &D;
GCCInstallCandidate SelectedInstallation;
/// On Biarch systems, this corresponds to the default multilib when
/// targeting the non-default multilib. Otherwise, it is empty.
std::optional<Multilib> BiarchSibling;
// We retain the list of install paths that were considered and rejected in
// order to print out detailed information in verbose mode.
std::set<std::string> CandidateGCCInstallPaths;
/// The set of multilibs that the detected installation supports.
MultilibSet Multilibs;
// Gentoo-specific toolchain configurations are stored here.
const std::string GentooConfigDir = "/etc/env.d/gcc";
public:
/// Function for converting a triple to a Debian multiarch. The
/// toolchains use this to adjust the target specific component of
/// include paths for Debian.
std::function<StringRef(const llvm::Triple &)> TripleToDebianMultiarch =
[](const llvm::Triple &T) {
StringRef S = T.str();
return S;
};
explicit GCCInstallationDetector(const Driver &D) : IsValid(false), D(D) {}
void init(const llvm::Triple &TargetTriple, const llvm::opt::ArgList &Args);
// TODO Replace isValid by changing SelectedInstallation into
// std::optional<SelectedInstallation>
// and move all accessors for fields of GCCInstallCandidate into
// that struct.
/// Check whether we detected a valid GCC install.
bool isValid() const { return IsValid; }
const GCCInstallCandidate &getSelectedInstallation() const {
return SelectedInstallation;
}
/// Get the GCC triple for the detected install.
const llvm::Triple &getTriple() const {
return SelectedInstallation.GCCTriple;
}
/// Get the detected GCC installation path.
StringRef getInstallPath() const {
return SelectedInstallation.GCCInstallPath;
}
/// Get the detected GCC parent lib path.
StringRef getParentLibPath() const {
return SelectedInstallation.GCCParentLibPath;
}
/// Get the detected Multilib
const Multilib &getMultilib() const {
return SelectedInstallation.SelectedMultilib;
}
/// Get the whole MultilibSet
const MultilibSet &getMultilibs() const { return Multilibs; }
@ -298,9 +244,7 @@ public:
bool getBiarchSibling(Multilib &M) const;
/// Get the detected GCC version string.
const GCCVersion &getVersion() const {
return SelectedInstallation.Version;
}
const GCCVersion &getVersion() const { return Version; }
/// Print information about the detected GCC installation.
void print(raw_ostream &OS) const;
@ -318,19 +262,6 @@ public:
SmallVectorImpl<std::string> &Prefixes,
StringRef SysRoot);
/// Checks if the \p GCCInstallation has libstdc++ include
/// directories.
bool GCCInstallationHasLibStdcxxIncludePaths(
const GCCInstallCandidate &GCCInstallation,
const llvm::opt::ArgList &DriverArgs) const;
/// Select a GCC installation directory from \p Installations and
/// set \p SelectedInstallation accordingly.
bool SelectGCCInstallationDirectory(
const SmallVector<GCCInstallCandidate, 3> &Installations,
const llvm::opt::ArgList &Args,
GCCInstallCandidate &SelectedInstallation) const;
bool ScanGCCForMultilibs(const llvm::Triple &TargetTriple,
const llvm::opt::ArgList &Args, StringRef Path,
bool NeedsBiarchSuffix = false);
@ -417,7 +348,8 @@ protected:
llvm::opt::ArgStringList &CC1Args) const;
bool addGCCLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC) const;
llvm::opt::ArgStringList &CC1Args,
StringRef DebianMultiarch) const;
bool addLibStdCXXIncludePaths(Twine IncludeDir, StringRef Triple,
Twine IncludeSuffix,

View File

@ -71,13 +71,6 @@ static StringRef getOSLibDir(const llvm::Triple &Triple, const ArgList &Args) {
Hurd::Hurd(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
: Generic_ELF(D, Triple, Args) {
GCCInstallation.TripleToDebianMultiarch = [](const llvm::Triple &T) {
StringRef TripleStr = T.str();
StringRef DebianMultiarch =
T.getArch() == llvm::Triple::x86 ? "i386-gnu" : TripleStr;
return DebianMultiarch;
};
GCCInstallation.init(Triple, Args);
Multilibs = GCCInstallation.getMultilibs();
SelectedMultilibs.assign({GCCInstallation.getMultilib()});
@ -214,7 +207,12 @@ void Hurd::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
if (!GCCInstallation.isValid())
return;
addGCCLibStdCxxIncludePaths(DriverArgs, CC1Args);
StringRef TripleStr = GCCInstallation.getTriple().str();
StringRef DebianMultiarch =
GCCInstallation.getTriple().getArch() == llvm::Triple::x86 ? "i386-gnu"
: TripleStr;
addGCCLibStdCxxIncludePaths(DriverArgs, CC1Args, DebianMultiarch);
}
void Hurd::addExtraOpts(llvm::opt::ArgStringList &CmdArgs) const {

View File

@ -211,13 +211,6 @@ static StringRef getOSLibDir(const llvm::Triple &Triple, const ArgList &Args) {
Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
: Generic_ELF(D, Triple, Args) {
GCCInstallation.TripleToDebianMultiarch = [](const llvm::Triple &T) {
StringRef TripleStr = T.str();
StringRef DebianMultiarch =
T.getArch() == llvm::Triple::x86 ? "i386-linux-gnu" : TripleStr;
return DebianMultiarch;
};
GCCInstallation.init(Triple, Args);
Multilibs = GCCInstallation.getMultilibs();
SelectedMultilibs.assign({GCCInstallation.getMultilib()});
@ -700,15 +693,22 @@ void Linux::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
if (!GCCInstallation.isValid())
return;
// Detect Debian g++-multiarch-incdir.diff.
StringRef TripleStr = GCCInstallation.getTriple().str();
StringRef DebianMultiarch =
GCCInstallation.getTriple().getArch() == llvm::Triple::x86
? "i386-linux-gnu"
: TripleStr;
// Try generic GCC detection first.
if (Generic_GCC::addGCCLibStdCxxIncludePaths(DriverArgs, CC1Args))
if (Generic_GCC::addGCCLibStdCxxIncludePaths(DriverArgs, CC1Args,
DebianMultiarch))
return;
StringRef LibDir = GCCInstallation.getParentLibPath();
const Multilib &Multilib = GCCInstallation.getMultilib();
const GCCVersion &Version = GCCInstallation.getVersion();
StringRef TripleStr = GCCInstallation.getTriple().str();
const std::string LibStdCXXIncludePathCandidates[] = {
// Android standalone toolchain has C++ headers in yet another place.
LibDir.str() + "/../" + TripleStr.str() + "/include/c++/" + Version.Text,

View File

@ -193,8 +193,10 @@ void Managarm::addLibStdCxxIncludePaths(
if (!GCCInstallation.isValid())
return;
StringRef TripleStr = GCCInstallation.getTriple().str();
// Try generic GCC detection.
addGCCLibStdCxxIncludePaths(DriverArgs, CC1Args);
Generic_GCC::addGCCLibStdCxxIncludePaths(DriverArgs, CC1Args, TripleStr);
}
SanitizerMask Managarm::getSupportedSanitizers() const {

View File

@ -1,28 +0,0 @@
// UNSUPPORTED: system-windows
// This file tests that the GCC installation directory detection takes
// the libstdc++ includes into account. In each directory
// Inputs/gcc_toolchain_libstdcxx/gccX, the installation directory for
// gcc X should be picked in the future since it is the directory with
// the largest version number which also contains the libstdc++
// include directory.
// RUN: %clang --gcc-toolchain=%S/Inputs/gcc_toolchain_libstdcxx/gcc10/usr -v 2>&1 |& FileCheck %s --check-prefix=GCC10
// GCC10: clang: warning: future releases of the clang compiler will prefer GCC installations containing libstdc++ include directories; '[[PREFIX:.*gcc_toolchain_libstdcxx/gcc10/usr/lib/gcc/x86_64-linux-gnu]]/10' would be chosen over '[[PREFIX]]/12' [-Wgcc-install-dir-libstdcxx]
// GCC10: Found candidate GCC installation: [[PREFIX]]/10
// GCC10: Found candidate GCC installation: [[PREFIX]]/11
// GCC10: Found candidate GCC installation: [[PREFIX]]/12
// GCC10: Selected GCC installation: [[PREFIX]]/12
// RUN: %clang --gcc-toolchain=%S/Inputs/gcc_toolchain_libstdcxx/gcc11/usr -v 2>&1 |& FileCheck %s --check-prefix=ONLY_GCC11
// ONLY_GCC11: clang: warning: future releases of the clang compiler will prefer GCC installations containing libstdc++ include directories; '[[PREFIX:.*gcc_toolchain_libstdcxx/gcc11/usr/lib/gcc/x86_64-linux-gnu]]/11' would be chosen over '[[PREFIX]]/12' [-Wgcc-install-dir-libstdcxx]
// ONLY_GCC11: Found candidate GCC installation: [[PREFIX]]/10
// ONLY_GCC11: Found candidate GCC installation: [[PREFIX]]/11
// ONLY_GCC11: Found candidate GCC installation: [[PREFIX]]/12
// ONLY_GCC11: Selected GCC installation: [[PREFIX]]/12
// RUN: %clang --gcc-toolchain=%S/Inputs/gcc_toolchain_libstdcxx/gcc12/usr -v 2>&1 |& FileCheck %s --check-prefix=GCC12
// GCC12: Found candidate GCC installation: [[PREFIX:.*gcc_toolchain_libstdcxx/gcc12/usr/lib/gcc/x86_64-linux-gnu]]/10
// GCC12: Found candidate GCC installation: [[PREFIX]]/11
// GCC12: Found candidate GCC installation: [[PREFIX]]/12
// GCC12: Selected GCC installation: [[PREFIX]]/12