[clang] ba7a1d9 - [Driver] move FreeBSD header search path management to the driver
Matt Jacobson via cfe-commits
cfe-commits at lists.llvm.org
Thu Nov 17 23:30:16 PST 2022
Author: Matt Jacobson
Date: 2022-11-18T02:29:49-05:00
New Revision: ba7a1d9e4aec5399e9cd45e47c7a548b1514b8ba
URL: https://github.com/llvm/llvm-project/commit/ba7a1d9e4aec5399e9cd45e47c7a548b1514b8ba
DIFF: https://github.com/llvm/llvm-project/commit/ba7a1d9e4aec5399e9cd45e47c7a548b1514b8ba.diff
LOG: [Driver] move FreeBSD header search path management to the driver
This matches OpenBSD, and it supports Swift's use of clang for its C interop
functionality. Recent changes to Swift use AddClangSystemIncludeArgs() to
inspect the cc1 args; this doesn't work for platforms where cc1 adds standard
include paths implicitly. See:
<https://github.com/apple/swift/commit/cf3354222d9f480de74db390f53a6dcc749fde14>
Also clean up InitHeaderSearch, making it clearer which targets manage header
search paths in the driver.
Differential Revision: https://reviews.llvm.org/D138183
Added:
Modified:
clang/lib/Driver/ToolChains/FreeBSD.cpp
clang/lib/Driver/ToolChains/FreeBSD.h
clang/lib/Lex/InitHeaderSearch.cpp
clang/test/Driver/freebsd.c
clang/test/Driver/freebsd.cpp
Removed:
################################################################################
diff --git a/clang/lib/Driver/ToolChains/FreeBSD.cpp b/clang/lib/Driver/ToolChains/FreeBSD.cpp
index fa6c11265ef89..64935227b07e1 100644
--- a/clang/lib/Driver/ToolChains/FreeBSD.cpp
+++ b/clang/lib/Driver/ToolChains/FreeBSD.cpp
@@ -11,6 +11,7 @@
#include "Arch/Mips.h"
#include "Arch/Sparc.h"
#include "CommonArgs.h"
+#include "clang/Config/config.h"
#include "clang/Driver/Compilation.h"
#include "clang/Driver/DriverDiagnostic.h"
#include "clang/Driver/Options.h"
@@ -408,6 +409,40 @@ unsigned FreeBSD::GetDefaultDwarfVersion() const {
return 4;
}
+void FreeBSD::AddClangSystemIncludeArgs(
+ const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args) const {
+ const Driver &D = getDriver();
+
+ if (DriverArgs.hasArg(clang::driver::options::OPT_nostdinc))
+ return;
+
+ if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
+ SmallString<128> Dir(D.ResourceDir);
+ llvm::sys::path::append(Dir, "include");
+ addSystemInclude(DriverArgs, CC1Args, Dir.str());
+ }
+
+ if (DriverArgs.hasArg(options::OPT_nostdlibinc))
+ return;
+
+ // Check for configure-time C include directories.
+ StringRef CIncludeDirs(C_INCLUDE_DIRS);
+ if (CIncludeDirs != "") {
+ SmallVector<StringRef, 5> dirs;
+ CIncludeDirs.split(dirs, ":");
+ for (StringRef dir : dirs) {
+ StringRef Prefix =
+ llvm::sys::path::is_absolute(dir) ? StringRef(D.SysRoot) : "";
+ addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir);
+ }
+ return;
+ }
+
+ addExternCSystemInclude(DriverArgs, CC1Args,
+ concat(D.SysRoot, "/usr/include"));
+}
+
void FreeBSD::addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const {
addSystemInclude(DriverArgs, CC1Args,
diff --git a/clang/lib/Driver/ToolChains/FreeBSD.h b/clang/lib/Driver/ToolChains/FreeBSD.h
index e9cba14174ec4..18832dad98847 100644
--- a/clang/lib/Driver/ToolChains/FreeBSD.h
+++ b/clang/lib/Driver/ToolChains/FreeBSD.h
@@ -58,6 +58,9 @@ class LLVM_LIBRARY_VISIBILITY FreeBSD : public Generic_ELF {
bool IsMathErrnoDefault() const override { return false; }
bool IsObjCNonFragileABIDefault() const override { return true; }
+ void
+ AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args) const override;
CXXStdlibType GetDefaultCXXStdlibType() const override;
void addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const override;
diff --git a/clang/lib/Lex/InitHeaderSearch.cpp b/clang/lib/Lex/InitHeaderSearch.cpp
index 0caa776b3bdbb..1f57742161fb2 100644
--- a/clang/lib/Lex/InitHeaderSearch.cpp
+++ b/clang/lib/Lex/InitHeaderSearch.cpp
@@ -42,9 +42,9 @@ struct DirectoryLookupInfo {
: Group(Group), Lookup(Lookup), UserEntryIdx(UserEntryIdx) {}
};
-/// InitHeaderSearch - This class makes it easier to set the search paths of
-/// a HeaderSearch object. InitHeaderSearch stores several search path lists
-/// internally, which can be sent to a HeaderSearch object in one swoop.
+/// This class makes it easier to set the search paths of a HeaderSearch object.
+/// InitHeaderSearch stores several search path lists internally, which can be
+/// sent to a HeaderSearch object in one swoop.
class InitHeaderSearch {
std::vector<DirectoryLookupInfo> IncludePath;
std::vector<std::pair<std::string, bool> > SystemHeaderPrefixes;
@@ -58,56 +58,54 @@ class InitHeaderSearch {
: Headers(HS), Verbose(verbose), IncludeSysroot(std::string(sysroot)),
HasSysroot(!(sysroot.empty() || sysroot == "/")) {}
- /// AddPath - Add the specified path to the specified group list, prefixing
- /// the sysroot if used.
+ /// Add the specified path to the specified group list, prefixing the sysroot
+ /// if used.
/// Returns true if the path exists, false if it was ignored.
bool AddPath(const Twine &Path, IncludeDirGroup Group, bool isFramework,
Optional<unsigned> UserEntryIdx = None);
- /// AddUnmappedPath - Add the specified path to the specified group list,
- /// without performing any sysroot remapping.
+ /// Add the specified path to the specified group list, without performing any
+ /// sysroot remapping.
/// Returns true if the path exists, false if it was ignored.
bool AddUnmappedPath(const Twine &Path, IncludeDirGroup Group,
bool isFramework,
Optional<unsigned> UserEntryIdx = None);
- /// AddSystemHeaderPrefix - Add the specified prefix to the system header
- /// prefix list.
+ /// Add the specified prefix to the system header prefix list.
void AddSystemHeaderPrefix(StringRef Prefix, bool IsSystemHeader) {
SystemHeaderPrefixes.emplace_back(std::string(Prefix), IsSystemHeader);
}
- /// AddGnuCPlusPlusIncludePaths - Add the necessary paths to support a gnu
- /// libstdc++.
+ /// Add the necessary paths to support a gnu libstdc++.
/// Returns true if the \p Base path was found, false if it does not exist.
bool AddGnuCPlusPlusIncludePaths(StringRef Base, StringRef ArchDir,
StringRef Dir32, StringRef Dir64,
const llvm::Triple &triple);
- /// AddMinGWCPlusPlusIncludePaths - Add the necessary paths to support a MinGW
- /// libstdc++.
+ /// Add the necessary paths to support a MinGW libstdc++.
void AddMinGWCPlusPlusIncludePaths(StringRef Base,
StringRef Arch,
StringRef Version);
- // AddDefaultCIncludePaths - Add paths that should always be searched.
+ /// Add paths that should always be searched.
void AddDefaultCIncludePaths(const llvm::Triple &triple,
const HeaderSearchOptions &HSOpts);
- // AddDefaultCPlusPlusIncludePaths - Add paths that should be searched when
- // compiling c++.
+ /// Add paths that should be searched when compiling c++.
void AddDefaultCPlusPlusIncludePaths(const LangOptions &LangOpts,
const llvm::Triple &triple,
const HeaderSearchOptions &HSOpts);
- /// AddDefaultSystemIncludePaths - Adds the default system include paths so
- /// that e.g. stdio.h is found.
+ /// Returns true iff AddDefaultIncludePaths should do anything. If this
+ /// returns false, include paths should instead be handled in the driver.
+ bool ShouldAddDefaultIncludePaths(const llvm::Triple &triple);
+
+ /// Adds the default system include paths so that e.g. stdio.h is found.
void AddDefaultIncludePaths(const LangOptions &Lang,
const llvm::Triple &triple,
const HeaderSearchOptions &HSOpts);
- /// Realize - Merges all search path lists into one list and send it to
- /// HeaderSearch.
+ /// Merges all search path lists into one list and send it to HeaderSearch.
void Realize(const LangOptions &Lang);
};
@@ -225,18 +223,15 @@ void InitHeaderSearch::AddMinGWCPlusPlusIncludePaths(StringRef Base,
void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple,
const HeaderSearchOptions &HSOpts) {
- llvm::Triple::OSType os = triple.getOS();
-
- if (triple.isOSDarwin()) {
+ if (!ShouldAddDefaultIncludePaths(triple))
llvm_unreachable("Include management is handled in the driver.");
- }
+
+ llvm::Triple::OSType os = triple.getOS();
if (HSOpts.UseStandardSystemIncludes) {
switch (os) {
case llvm::Triple::CloudABI:
- case llvm::Triple::FreeBSD:
case llvm::Triple::NetBSD:
- case llvm::Triple::OpenBSD:
case llvm::Triple::NaCl:
case llvm::Triple::PS4:
case llvm::Triple::PS5:
@@ -280,12 +275,6 @@ void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple,
}
switch (os) {
- case llvm::Triple::Linux:
- case llvm::Triple::Hurd:
- case llvm::Triple::Solaris:
- case llvm::Triple::OpenBSD:
- llvm_unreachable("Include management is handled in the driver.");
-
case llvm::Triple::CloudABI: {
// <sysroot>/<triple>/include
SmallString<128> P = StringRef(HSOpts.ResourceDir);
@@ -386,20 +375,12 @@ void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple,
void InitHeaderSearch::AddDefaultCPlusPlusIncludePaths(
const LangOptions &LangOpts, const llvm::Triple &triple,
const HeaderSearchOptions &HSOpts) {
- llvm::Triple::OSType os = triple.getOS();
- // FIXME: temporary hack: hard-coded paths.
-
- if (triple.isOSDarwin()) {
+ if (!ShouldAddDefaultIncludePaths(triple))
llvm_unreachable("Include management is handled in the driver.");
- }
+ // FIXME: temporary hack: hard-coded paths.
+ llvm::Triple::OSType os = triple.getOS();
switch (os) {
- case llvm::Triple::Linux:
- case llvm::Triple::Hurd:
- case llvm::Triple::Solaris:
- case llvm::Triple::AIX:
- llvm_unreachable("Include management is handled in the driver.");
- break;
case llvm::Triple::Win32:
switch (triple.getEnvironment()) {
default: llvm_unreachable("Include management is handled in the driver.");
@@ -425,46 +406,56 @@ void InitHeaderSearch::AddDefaultCPlusPlusIncludePaths(
}
}
-void InitHeaderSearch::AddDefaultIncludePaths(const LangOptions &Lang,
- const llvm::Triple &triple,
- const HeaderSearchOptions &HSOpts) {
- // NB: This code path is going away. All of the logic is moving into the
- // driver which has the information necessary to do target-specific
- // selections of default include paths. Each target which moves there will be
- // exempted from this logic here until we can delete the entire pile of code.
+bool InitHeaderSearch::ShouldAddDefaultIncludePaths(
+ const llvm::Triple &triple) {
switch (triple.getOS()) {
- default:
- break; // Everything else continues to use this routine's logic.
-
+ case llvm::Triple::AIX:
case llvm::Triple::Emscripten:
- case llvm::Triple::Linux:
+ case llvm::Triple::FreeBSD:
case llvm::Triple::Hurd:
+ case llvm::Triple::Linux:
case llvm::Triple::OpenBSD:
case llvm::Triple::Solaris:
case llvm::Triple::WASI:
- case llvm::Triple::AIX:
- return;
+ return false;
case llvm::Triple::Win32:
if (triple.getEnvironment() != llvm::Triple::Cygnus ||
triple.isOSBinFormatMachO())
- return;
+ return false;
break;
case llvm::Triple::UnknownOS:
if (triple.isWasm())
- return;
+ return false;
+ break;
+
+ default:
break;
}
- // All header search logic is handled in the Driver for Darwin.
+ return true; // Everything else uses AddDefaultIncludePaths().
+}
+
+void InitHeaderSearch::AddDefaultIncludePaths(
+ const LangOptions &Lang, const llvm::Triple &triple,
+ const HeaderSearchOptions &HSOpts) {
+ // NB: This code path is going away. All of the logic is moving into the
+ // driver which has the information necessary to do target-specific
+ // selections of default include paths. Each target which moves there will be
+ // exempted from this logic in ShouldAddDefaultIncludePaths() until we can
+ // delete the entire pile of code.
+ if (!ShouldAddDefaultIncludePaths(triple))
+ return;
+
+ // NOTE: some additional header search logic is handled in the driver for
+ // Darwin.
if (triple.isOSDarwin()) {
if (HSOpts.UseStandardSystemIncludes) {
// Add the default framework include paths on Darwin.
if (triple.isDriverKit()) {
AddPath("/System/DriverKit/System/Library/Frameworks", System, true);
- }
- else {
+ } else {
AddPath("/System/Library/Frameworks", System, true);
AddPath("/Library/Frameworks", System, true);
}
@@ -484,9 +475,9 @@ void InitHeaderSearch::AddDefaultIncludePaths(const LangOptions &Lang,
AddDefaultCIncludePaths(triple, HSOpts);
}
-/// RemoveDuplicates - If there are duplicate directory entries in the specified
-/// search list, remove the later (dead) ones. Returns the number of non-system
-/// headers removed, which is used to update NumAngled.
+/// If there are duplicate directory entries in the specified search list,
+/// remove the later (dead) ones. Returns the number of non-system headers
+/// removed, which is used to update NumAngled.
static unsigned RemoveDuplicates(std::vector<DirectoryLookupInfo> &SearchList,
unsigned First, bool Verbose) {
llvm::SmallPtrSet<const DirectoryEntry *, 8> SeenDirs;
diff --git a/clang/test/Driver/freebsd.c b/clang/test/Driver/freebsd.c
index eecd07d012be3..1091f3b0cff0d 100644
--- a/clang/test/Driver/freebsd.c
+++ b/clang/test/Driver/freebsd.c
@@ -213,3 +213,10 @@
// RELOCATABLE-NOT: "-dynamic-linker"
// RELOCATABLE-NOT: "-l
// RELOCATABLE-NOT: crt{{[^./]+}}.o
+
+// Check that the driver passes include paths to cc1 on FreeBSD.
+// RUN: %clang -### %s --target=x86_64-unknown-freebsd13.1 -r 2>&1 \
+// RUN: | FileCheck %s --check-prefix=DRIVER-PASS-INCLUDES
+// DRIVER-PASS-INCLUDES: "-cc1" {{.*}}"-resource-dir" "[[RESOURCE:[^"]+]]"
+// DRIVER-PASS-INCLUDES-SAME: {{^}} "-internal-isystem" "[[RESOURCE]]{{/|\\\\}}include"
+// DRIVER-PASS-INCLUDES-SAME: {{^}} "-internal-externc-isystem" "/usr/include"
diff --git a/clang/test/Driver/freebsd.cpp b/clang/test/Driver/freebsd.cpp
index 56c3d3cba1fe5..6b1b09055ab84 100644
--- a/clang/test/Driver/freebsd.cpp
+++ b/clang/test/Driver/freebsd.cpp
@@ -40,3 +40,11 @@
// CHECK-LIBCXX-SYSROOT-SLASH: "-cc1"
// CHECK-LIBCXX-SYSROOT-SLASH-SAME: "-isysroot" "[[SYSROOT:[^"]+/]]"
// CHECK-LIBCXX-SYSROOT-SLASH-SAME: "-internal-isystem" "[[SYSROOT]]usr/include/c++/v1"
+
+// Check that the driver passes include paths to cc1 on FreeBSD.
+// RUN: %clang -### %s --target=x86_64-unknown-freebsd13.1 -r 2>&1 \
+// RUN: | FileCheck %s --check-prefix=DRIVER-PASS-INCLUDES
+// DRIVER-PASS-INCLUDES: "-cc1" {{.*}}"-resource-dir" "[[RESOURCE:[^"]+]]"
+// DRIVER-PASS-INCLUDES-SAME: {{^}} "-internal-isystem" "/usr/include/c++/v1"
+// DRIVER-PASS-INCLUDES-SAME: {{^}} "-internal-isystem" "[[RESOURCE]]{{/|\\\\}}include"
+// DRIVER-PASS-INCLUDES-SAME: {{^}} "-internal-externc-isystem" "/usr/include"
More information about the cfe-commits
mailing list