[clang] Support '-fmodule-file-home-is-cwd' for C++ modules. (PR #135147)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Apr 10 02:13:03 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-modules
Author: Michael Park (mpark)
<details>
<summary>Changes</summary>
`-fmodule-file-home-is-cwd` was added in https://github.com/llvm/llvm-project/commit/646e502de0d854cb3ecaca90ab52bebfe59a40cd to support relocatable PCMs for Clang modules. This PR extends the functionality to allow standard C++ modules to be relocatable.
---
Full diff: https://github.com/llvm/llvm-project/pull/135147.diff
2 Files Affected:
- (modified) clang/lib/Serialization/ASTWriter.cpp (+35-33)
- (added) clang/test/Modules/relocatable-modules.cpp (+43)
``````````diff
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index a48c05061626a..ae771f8f014e4 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -1493,42 +1493,44 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, StringRef isysroot) {
unsigned AbbrevCode = Stream.EmitAbbrev(std::move(Abbrev));
RecordData::value_type Record[] = {MODULE_NAME};
Stream.EmitRecordWithBlob(AbbrevCode, Record, WritingModule->Name);
- }
- if (WritingModule && WritingModule->Directory) {
- SmallString<128> BaseDir;
- if (PP.getHeaderSearchInfo().getHeaderSearchOpts().ModuleFileHomeIsCwd) {
- // Use the current working directory as the base path for all inputs.
- auto CWD = FileMgr.getOptionalDirectoryRef(".");
- BaseDir.assign(CWD->getName());
- } else {
- BaseDir.assign(WritingModule->Directory->getName());
- }
- cleanPathForOutput(FileMgr, BaseDir);
-
- // If the home of the module is the current working directory, then we
- // want to pick up the cwd of the build process loading the module, not
- // our cwd, when we load this module.
- if (!PP.getHeaderSearchInfo().getHeaderSearchOpts().ModuleFileHomeIsCwd &&
- (!PP.getHeaderSearchInfo()
- .getHeaderSearchOpts()
- .ModuleMapFileHomeIsCwd ||
- WritingModule->Directory->getName() != ".")) {
- // Module directory.
- auto Abbrev = std::make_shared<BitCodeAbbrev>();
- Abbrev->Add(BitCodeAbbrevOp(MODULE_DIRECTORY));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Directory
- unsigned AbbrevCode = Stream.EmitAbbrev(std::move(Abbrev));
+ auto BaseDir = [&]() -> std::optional<SmallString<128>> {
+ if (PP.getHeaderSearchInfo().getHeaderSearchOpts().ModuleFileHomeIsCwd) {
+ // Use the current working directory as the base path for all inputs.
+ auto CWD = FileMgr.getOptionalDirectoryRef(".");
+ return CWD->getName();
+ }
+ if (WritingModule->Directory) {
+ return WritingModule->Directory->getName();
+ }
+ return std::nullopt;
+ }();
+ if (BaseDir) {
+ cleanPathForOutput(FileMgr, *BaseDir);
+ // If the home of the module is the current working directory, then we
+ // want to pick up the cwd of the build process loading the module, not
+ // our cwd, when we load this module.
+ if (!PP.getHeaderSearchInfo().getHeaderSearchOpts().ModuleFileHomeIsCwd &&
+ (!PP.getHeaderSearchInfo()
+ .getHeaderSearchOpts()
+ .ModuleMapFileHomeIsCwd ||
+ WritingModule->Directory->getName() != ".")) {
+ // Module directory.
+ auto Abbrev = std::make_shared<BitCodeAbbrev>();
+ Abbrev->Add(BitCodeAbbrevOp(MODULE_DIRECTORY));
+ Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Directory
+ unsigned AbbrevCode = Stream.EmitAbbrev(std::move(Abbrev));
+
+ RecordData::value_type Record[] = {MODULE_DIRECTORY};
+ Stream.EmitRecordWithBlob(AbbrevCode, Record, *BaseDir);
+ }
- RecordData::value_type Record[] = {MODULE_DIRECTORY};
- Stream.EmitRecordWithBlob(AbbrevCode, Record, BaseDir);
+ // Write out all other paths relative to the base directory if possible.
+ BaseDirectory.assign(BaseDir->begin(), BaseDir->end());
+ } else if (!isysroot.empty()) {
+ // Write out paths relative to the sysroot if possible.
+ BaseDirectory = std::string(isysroot);
}
-
- // Write out all other paths relative to the base directory if possible.
- BaseDirectory.assign(BaseDir.begin(), BaseDir.end());
- } else if (!isysroot.empty()) {
- // Write out paths relative to the sysroot if possible.
- BaseDirectory = std::string(isysroot);
}
// Module map file
diff --git a/clang/test/Modules/relocatable-modules.cpp b/clang/test/Modules/relocatable-modules.cpp
new file mode 100644
index 0000000000000..27e7330835b34
--- /dev/null
+++ b/clang/test/Modules/relocatable-modules.cpp
@@ -0,0 +1,43 @@
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+
+// CHECK-NOT: MODULE_DIRECTORY
+
+// RUN: cd %t
+// RUN: %clang_cc1 -std=c++20 -emit-module-interface %t/a.cppm -o %t/a-abs.pcm
+
+// RUN: llvm-bcanalyzer --dump --disable-histogram %t/a-abs.pcm | FileCheck %s
+// RUN: llvm-bcanalyzer --dump --disable-histogram %t/a-abs.pcm \
+// RUN: | FileCheck %s --check-prefix=INPUT-ABS -DPREFIX=%t
+
+// RUN: %clang_cc1 -std=c++20 -emit-module-interface %t/a.cppm -o %t/a-rel.pcm \
+// RUN: -fmodule-file-home-is-cwd
+
+// RUN: llvm-bcanalyzer --dump --disable-histogram %t/a-rel.pcm | FileCheck %s
+// RUN: llvm-bcanalyzer --dump --disable-histogram %t/a-rel.pcm \
+// RUN: | FileCheck %s --check-prefix=INPUT-REL
+
+// INPUT-ABS: <INPUT_FILE {{.*}}/> blob data = '[[PREFIX]]{{/|\\}}a.cppm'
+// INPUT-REL: <INPUT_FILE {{.*}}/> blob data = 'a.cppm'
+
+//--- a.cppm
+export module a;
+
+// RUN: cd %S
+// RUN: %clang_cc1 -std=c++20 -emit-header-unit -xc++-user-header Inputs/cxx-header.h \
+// RUN: -o %t/cxx-header-abs.pcm
+
+// RUN: llvm-bcanalyzer --dump --disable-histogram %t/cxx-header-abs.pcm | FileCheck %s
+// RUN: llvm-bcanalyzer --dump --disable-histogram %t/cxx-header-abs.pcm \
+// RUN: | FileCheck %s --check-prefix=HU-INPUT-ABS -DPREFIX=%S
+
+// RUN: %clang_cc1 -std=c++20 -emit-header-unit -xc++-user-header Inputs/cxx-header.h \
+// RUN: -fmodule-file-home-is-cwd -o %t/cxx-header-rel.pcm
+
+// RUN: llvm-bcanalyzer --dump --disable-histogram %t/cxx-header-rel.pcm | FileCheck %s
+// RUN: llvm-bcanalyzer --dump --disable-histogram %t/cxx-header-rel.pcm \
+// RUN: | FileCheck %s --check-prefix=HU-INPUT-REL
+
+// HU-INPUT-ABS: <INPUT_FILE {{.*}}/> blob data = '[[PREFIX]]{{/|\\}}Inputs{{/|\\}}cxx-header.h'
+// HU-INPUT-REL: <INPUT_FILE {{.*}}/> blob data = 'Inputs{{/|\\}}cxx-header.h'
``````````
</details>
https://github.com/llvm/llvm-project/pull/135147
More information about the cfe-commits
mailing list