https://github.com/rmaz updated https://github.com/llvm/llvm-project/pull/68023
>From 9d5ae4b53558614bdf9681bbefd02cf04aeb107b Mon Sep 17 00:00:00 2001 From: Richard Howell <r...@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 | 14 +++++++++++--- clang/lib/Lex/PPDirectives.cpp | 9 ++++++++- .../Inputs/builtin-headers/module.modulemap | 3 +++ clang/test/Modules/relative-resource-dir.m | 11 +++++++++++ 5 files changed, 37 insertions(+), 5 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 fc49742ad4af2c1..545d07c071c40e5 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 e8437572ebf4bf6..d1c7b855b9bc919 100644 --- a/clang/lib/Lex/ModuleMap.cpp +++ b/clang/lib/Lex/ModuleMap.cpp @@ -180,8 +180,9 @@ static void appendSubframeworkPaths(Module *Mod, OptionalFileEntryRef ModuleMap::findHeader( Module *M, const Module::UnresolvedHeaderDirective &Header, SmallVectorImpl<char> &RelativePathName, bool &NeedsFramework) { - // Search for the header file within the module's home directory. - auto Directory = M->Directory; + // Search for the header file within the module's home directory + // or the builtin include dir if this is a builtin header. + auto Directory = Header.HasBuiltinHeader ? BuiltinIncludeDir : M->Directory; SmallString<128> FullPathName(Directory->getName()); auto GetFile = [&](StringRef Filename) -> OptionalFileEntryRef { @@ -348,8 +349,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 +418,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 7899bfa1c4f5842..5d6aa4906b757d9 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" @@ -981,7 +983,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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits