Skip to content

Commit fcf6800

Browse files
committed
[Driver] Move detectLibcxxIncludePath to ToolChain
This helper method is useful even outside of Gnu toolchains, so move it to ToolChain so it can be reused in other toolchains such as Fuchsia. Differential Revision: https://reviews.llvm.org/D88452
1 parent 45783d0 commit fcf6800

File tree

5 files changed

+35
-26
lines changed

5 files changed

+35
-26
lines changed

clang/include/clang/Driver/ToolChain.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,9 @@ class ToolChain {
603603
// given compilation arguments.
604604
virtual UnwindLibType GetUnwindLibType(const llvm::opt::ArgList &Args) const;
605605

606+
// Detect the highest available version of libc++ in include path.
607+
virtual std::string detectLibcxxVersion(StringRef IncludePath) const;
608+
606609
/// AddClangCXXStdlibIncludeArgs - Add the clang -cc1 level arguments to set
607610
/// the include paths to use for the given C++ standard library type.
608611
virtual void

clang/lib/Driver/ToolChain.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -898,6 +898,29 @@ void ToolChain::addExternCSystemIncludeIfExists(const ArgList &DriverArgs,
898898
}
899899
}
900900

901+
std::string ToolChain::detectLibcxxVersion(StringRef IncludePath) const {
902+
std::error_code EC;
903+
int MaxVersion = 0;
904+
std::string MaxVersionString;
905+
SmallString<128> Path(IncludePath);
906+
llvm::sys::path::append(Path, "c++");
907+
for (llvm::vfs::directory_iterator LI = getVFS().dir_begin(Path, EC), LE;
908+
!EC && LI != LE; LI = LI.increment(EC)) {
909+
StringRef VersionText = llvm::sys::path::filename(LI->path());
910+
int Version;
911+
if (VersionText[0] == 'v' &&
912+
!VersionText.slice(1, StringRef::npos).getAsInteger(10, Version)) {
913+
if (Version > MaxVersion) {
914+
MaxVersion = Version;
915+
MaxVersionString = std::string(VersionText);
916+
}
917+
}
918+
}
919+
if (!MaxVersion)
920+
return "";
921+
return MaxVersionString;
922+
}
923+
901924
void ToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
902925
ArgStringList &CC1Args) const {
903926
// Header search paths should be handled by each of the subclasses.

clang/lib/Driver/ToolChains/Fuchsia.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,9 @@ void Fuchsia::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
365365
switch (GetCXXStdlibType(DriverArgs)) {
366366
case ToolChain::CST_Libcxx: {
367367
SmallString<128> P(getDriver().Dir);
368-
llvm::sys::path::append(P, "..", "include", "c++", "v1");
368+
llvm::sys::path::append(P, "..", "include");
369+
std::string Version = detectLibcxxVersion(P);
370+
llvm::sys::path::append(P, "c++", Version);
369371
addSystemInclude(DriverArgs, CC1Args, P.str());
370372
break;
371373
}

clang/lib/Driver/ToolChains/Gnu.cpp

Lines changed: 6 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2892,48 +2892,29 @@ void Generic_GCC::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
28922892
}
28932893
}
28942894

2895-
static std::string DetectLibcxxIncludePath(llvm::vfs::FileSystem &vfs,
2896-
StringRef base) {
2897-
std::error_code EC;
2898-
int MaxVersion = 0;
2899-
std::string MaxVersionString;
2900-
for (llvm::vfs::directory_iterator LI = vfs.dir_begin(base, EC), LE;
2901-
!EC && LI != LE; LI = LI.increment(EC)) {
2902-
StringRef VersionText = llvm::sys::path::filename(LI->path());
2903-
int Version;
2904-
if (VersionText[0] == 'v' &&
2905-
!VersionText.slice(1, StringRef::npos).getAsInteger(10, Version)) {
2906-
if (Version > MaxVersion) {
2907-
MaxVersion = Version;
2908-
MaxVersionString = std::string(VersionText);
2909-
}
2910-
}
2911-
}
2912-
return MaxVersion ? (base + "/" + MaxVersionString).str() : "";
2913-
}
2914-
29152895
void
29162896
Generic_GCC::addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
29172897
llvm::opt::ArgStringList &CC1Args) const {
29182898
auto AddIncludePath = [&](std::string Path) {
2919-
std::string IncludePath = DetectLibcxxIncludePath(getVFS(), Path);
2920-
if (IncludePath.empty() || !getVFS().exists(IncludePath))
2899+
std::string Version = detectLibcxxVersion(Path);
2900+
std::string IncludePath = Path + "/c++/" + Version;
2901+
if (Version.empty() || !getVFS().exists(IncludePath))
29212902
return false;
29222903
addSystemInclude(DriverArgs, CC1Args, IncludePath);
29232904
return true;
29242905
};
29252906
// Android never uses the libc++ headers installed alongside the toolchain,
29262907
// which are generally incompatible with the NDK libraries anyway.
29272908
if (!getTriple().isAndroid())
2928-
if (AddIncludePath(getDriver().Dir + "/../include/c++"))
2909+
if (AddIncludePath(getDriver().Dir + "/../include"))
29292910
return;
29302911
// If this is a development, non-installed, clang, libcxx will
29312912
// not be found at ../include/c++ but it likely to be found at
29322913
// one of the following two locations:
29332914
std::string SysRoot = computeSysRoot();
2934-
if (AddIncludePath(SysRoot + "/usr/local/include/c++"))
2915+
if (AddIncludePath(SysRoot + "/usr/local/include"))
29352916
return;
2936-
if (AddIncludePath(SysRoot + "/usr/include/c++"))
2917+
if (AddIncludePath(SysRoot + "/usr/include"))
29372918
return;
29382919
}
29392920

clang/test/Driver/Inputs/basic_fuchsia_tree/include/c++/v1/.keep

Whitespace-only changes.

0 commit comments

Comments
 (0)