[clang] [clang] use relative paths for builtin headers during module compilation (PR #68023)

Richard Howell via cfe-commits cfe-commits at lists.llvm.org
Thu Oct 26 07:41:50 PDT 2023


https://github.com/rmaz updated https://github.com/llvm/llvm-project/pull/68023

>From cf4ae971c3fd30f705fa79b8b918288649766d14 Mon Sep 17 00:00:00 2001
From: Richard Howell <rhow at fb.com>
Date: Mon, 2 Oct 2023 11:10:52 -0700
Subject: [PATCH] [clang] add module builtin headers relative to resource dir

When including builtin headers as part of a system module, serialize
them relative to the builtin include dir. To handle later lookup
add a method to provide the correct base directory. This makes it
possible to compile modules including builtin headers with
relative resource dirs.
---
 clang/include/clang/Lex/ModuleMap.h                   |  5 ++++-
 clang/lib/Lex/ModuleMap.cpp                           |  9 ++++++++-
 clang/lib/Lex/PPDirectives.cpp                        |  9 ++++++++-
 .../Modules/Inputs/builtin-headers/module.modulemap   |  3 +++
 clang/test/Modules/relative-resource-dir.m            | 11 +++++++++++
 5 files changed, 34 insertions(+), 3 deletions(-)
 create mode 100644 clang/test/Modules/Inputs/builtin-headers/module.modulemap
 create mode 100644 clang/test/Modules/relative-resource-dir.m

diff --git a/clang/include/clang/Lex/ModuleMap.h b/clang/include/clang/Lex/ModuleMap.h
index 054d4211b9c6d41..69ec8f34a324255 100644
--- a/clang/include/clang/Lex/ModuleMap.h
+++ b/clang/include/clang/Lex/ModuleMap.h
@@ -410,13 +410,16 @@ class ModuleMap {
   }
 
   /// Get the directory that contains Clang-supplied include files.
-  const DirectoryEntry *getBuiltinDir() const {
+  OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr getBuiltinDir() const {
     return BuiltinIncludeDir;
   }
 
   /// Is this a compiler builtin header?
   bool isBuiltinHeader(FileEntryRef File);
 
+  bool shouldImportRelativeToBuiltinIncludeDir(StringRef FileName,
+                                               Module *Module) const;
+
   /// Add a module map callback.
   void addModuleMapCallbacks(std::unique_ptr<ModuleMapCallbacks> Callback) {
     Callbacks.push_back(std::move(Callback));
diff --git a/clang/lib/Lex/ModuleMap.cpp b/clang/lib/Lex/ModuleMap.cpp
index eb7cab54386c480..e4f3cdd3b163f50 100644
--- a/clang/lib/Lex/ModuleMap.cpp
+++ b/clang/lib/Lex/ModuleMap.cpp
@@ -348,8 +348,8 @@ bool ModuleMap::resolveAsBuiltinHeader(
   if (!File)
     return false;
 
+  Module::Header H = {Header.FileName, Header.FileName, *File};
   auto Role = headerKindToRole(Header.Kind);
-  Module::Header H = {Header.FileName, std::string(Path.str()), *File};
   addHeader(Mod, H, Role);
   return true;
 }
@@ -417,6 +417,13 @@ bool ModuleMap::isBuiltinHeader(FileEntryRef File) {
          isBuiltinHeaderName(llvm::sys::path::filename(File.getName()));
 }
 
+bool ModuleMap::shouldImportRelativeToBuiltinIncludeDir(StringRef FileName,
+                                                        Module *Module) const {
+  return LangOpts.BuiltinHeadersInSystemModules && BuiltinIncludeDir &&
+         Module->IsSystem && !Module->isPartOfFramework() &&
+         isBuiltinHeaderName(FileName);
+}
+
 ModuleMap::HeadersMap::iterator ModuleMap::findKnownHeader(FileEntryRef File) {
   resolveHeaderDirectives(File);
   HeadersMap::iterator Known = Headers.find(File);
diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp
index 2892d4b777846ff..6fd515a5f0c756b 100644
--- a/clang/lib/Lex/PPDirectives.cpp
+++ b/clang/lib/Lex/PPDirectives.cpp
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Basic/CharInfo.h"
+#include "clang/Basic/DirectoryEntry.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/IdentifierTable.h"
 #include "clang/Basic/LangOptions.h"
@@ -21,6 +22,7 @@
 #include "clang/Basic/TokenKinds.h"
 #include "clang/Lex/CodeCompletionHandler.h"
 #include "clang/Lex/HeaderSearch.h"
+#include "clang/Lex/HeaderSearchOptions.h"
 #include "clang/Lex/LexDiagnostic.h"
 #include "clang/Lex/LiteralSupport.h"
 #include "clang/Lex/MacroInfo.h"
@@ -982,7 +984,12 @@ OptionalFileEntryRef Preprocessor::LookupFile(
     // map file.
     if (!FileEnt) {
       if (FID == SourceMgr.getMainFileID() && MainFileDir) {
-        Includers.push_back(std::make_pair(std::nullopt, *MainFileDir));
+        auto IncludeDir =
+            HeaderInfo.getModuleMap().shouldImportRelativeToBuiltinIncludeDir(
+                Filename, getCurrentModule())
+                ? HeaderInfo.getModuleMap().getBuiltinDir()
+                : MainFileDir;
+        Includers.push_back(std::make_pair(std::nullopt, *IncludeDir));
         BuildSystemModule = getCurrentModule()->IsSystem;
       } else if ((FileEnt = SourceMgr.getFileEntryRefForID(
                       SourceMgr.getMainFileID()))) {
diff --git a/clang/test/Modules/Inputs/builtin-headers/module.modulemap b/clang/test/Modules/Inputs/builtin-headers/module.modulemap
new file mode 100644
index 000000000000000..78a5b730dc6a925
--- /dev/null
+++ b/clang/test/Modules/Inputs/builtin-headers/module.modulemap
@@ -0,0 +1,3 @@
+module ModuleWithBuiltinHeader [system] {
+    header "float.h"
+}
\ No newline at end of file
diff --git a/clang/test/Modules/relative-resource-dir.m b/clang/test/Modules/relative-resource-dir.m
new file mode 100644
index 000000000000000..2efc61259fd7891
--- /dev/null
+++ b/clang/test/Modules/relative-resource-dir.m
@@ -0,0 +1,11 @@
+// REQUIRES: shell
+
+// RUN: EXPECTED_RESOURCE_DIR=`%clang -print-resource-dir` && \
+// RUN:  mkdir -p %t && rm -rf %t/resource-dir && \
+// RUN:  cp -R $EXPECTED_RESOURCE_DIR %t/resource-dir
+// RUN: cd %t && %clang -cc1 -x objective-c -fmodules -fmodule-format=obj \
+// RUN:   -fimplicit-module-maps -fmodules-cache-path=%t.mcp \
+// RUN:   -fbuiltin-headers-in-system-modules \
+// RUN:   -resource-dir resource-dir \
+// RUN:   -emit-module %S/Inputs/builtin-headers/module.modulemap \
+// RUN:   -fmodule-name=ModuleWithBuiltinHeader -o %t.pcm



More information about the cfe-commits mailing list