[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