[clang] d9cea8d - [C++20][Modules][HU 4/5] Handle pre-processed header units.

Iain Sandoe via cfe-commits cfe-commits at lists.llvm.org
Sun Mar 27 01:39:02 PDT 2022


Author: Iain Sandoe
Date: 2022-03-27T09:38:06+01:00
New Revision: d9cea8d3a8fff86672174780312674871729578c

URL: https://github.com/llvm/llvm-project/commit/d9cea8d3a8fff86672174780312674871729578c
DIFF: https://github.com/llvm/llvm-project/commit/d9cea8d3a8fff86672174780312674871729578c.diff

LOG: [C++20][Modules][HU 4/5] Handle pre-processed header units.

We wish to support emitting a pre-processed output for an importable
header unit, that can be consumed to produce the same header units as
the original source.

This means that ee need to find the original filename used to produce
the re-preprocessed output, so that it can be assigned as the module
name.  This is peeked from the first line of the pre-processed source
when the action sets up the files.

Differential Revision: https://reviews.llvm.org/D121098

Added: 
    clang/test/Modules/cxx20-hu-05.cpp

Modified: 
    clang/lib/Frontend/FrontendAction.cpp
    clang/lib/Sema/SemaModule.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Frontend/FrontendAction.cpp b/clang/lib/Frontend/FrontendAction.cpp
index 68b823252130c..45245f3f0fef4 100644
--- a/clang/lib/Frontend/FrontendAction.cpp
+++ b/clang/lib/Frontend/FrontendAction.cpp
@@ -843,6 +843,21 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
   if (!CI.InitializeSourceManager(Input))
     return false;
 
+  if (CI.getLangOpts().CPlusPlusModules && Input.getKind().isHeaderUnit() &&
+      Input.getKind().isPreprocessed() && !usesPreprocessorOnly()) {
+    // We have an input filename like foo.iih, but we want to find the right
+    // module name (and original file, to build the map entry).
+    // Check if the first line specifies the original source file name with a
+    // linemarker.
+    std::string PresumedInputFile = std::string(getCurrentFileOrBufferName());
+    ReadOriginalFileName(CI, PresumedInputFile);
+    // Unless the user overrides this, the module name is the name by which the
+    // original file was known.
+    if (CI.getLangOpts().ModuleName.empty())
+      CI.getLangOpts().ModuleName = std::string(PresumedInputFile);
+    CI.getLangOpts().CurrentModule = CI.getLangOpts().ModuleName;
+  }
+
   // For module map files, we first parse the module map and synthesize a
   // "<module-includes>" buffer before more conventional processing.
   if (Input.getKind().getFormat() == InputKind::ModuleMap) {

diff  --git a/clang/lib/Sema/SemaModule.cpp b/clang/lib/Sema/SemaModule.cpp
index e28de8c79b273..893b913194aae 100644
--- a/clang/lib/Sema/SemaModule.cpp
+++ b/clang/lib/Sema/SemaModule.cpp
@@ -109,10 +109,18 @@ void Sema::HandleStartOfHeaderUnit() {
     const_cast<LangOptions &>(getLangOpts()).CurrentModule = HUName.str();
   }
 
-  auto &Map = PP.getHeaderSearchInfo().getModuleMap();
   // TODO: Make the C++20 header lookup independent.
-  Module::Header H{getLangOpts().CurrentModule, getLangOpts().CurrentModule,
-                   SourceMgr.getFileEntryForID(SourceMgr.getMainFileID())};
+  // When the input is pre-processed source, we need a file ref to the original
+  // file for the header map.
+  auto F = SourceMgr.getFileManager().getFile(HUName);
+  // For the sake of error recovery (if someone has moved the original header
+  // after creating the pre-processed output) fall back to obtaining the file
+  // ref for the input file, which must be present.
+  if (!F)
+    F = SourceMgr.getFileEntryForID(SourceMgr.getMainFileID());
+  assert(F && "failed to find the header unit source?");
+  Module::Header H{HUName.str(), HUName.str(), *F};
+  auto &Map = PP.getHeaderSearchInfo().getModuleMap();
   Module *Mod = Map.createHeaderUnit(StartOfTU, HUName, H);
   assert(Mod && "module creation should not fail");
   ModuleScopes.push_back({}); // No GMF

diff  --git a/clang/test/Modules/cxx20-hu-05.cpp b/clang/test/Modules/cxx20-hu-05.cpp
new file mode 100644
index 0000000000000..b0d7c0f3c9e76
--- /dev/null
+++ b/clang/test/Modules/cxx20-hu-05.cpp
@@ -0,0 +1,32 @@
+// Test macro preservation in C++20 Header Units.
+
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+// RUN: cd %t
+
+// Produce a pre-processed file.
+// RUN: %clang_cc1 -std=c++20 -E -xc++-user-header hu-01.h -o hu-01.iih
+
+// consume that to produce the heder unit.
+// RUN: %clang_cc1 -std=c++20 -emit-header-unit \
+// RUN: -xc++-header-unit-header-cpp-output hu-01.iih -o hu-01.pcm
+
+// check that the header unit is named for the original file, not the .iih.
+// RUN: %clang_cc1 -std=c++20 -module-file-info hu-01.pcm | \
+// RUN: FileCheck --check-prefix=CHECK-HU %s -DTDIR=%t
+
+//--- hu-01.h
+#ifndef __GUARD
+#define __GUARD
+
+int baz(int);
+#define FORTYTWO 42
+
+#define SHOULD_NOT_BE_DEFINED -1
+#undef SHOULD_NOT_BE_DEFINED
+
+#endif // __GUARD
+
+// CHECK-HU:  ====== C++20 Module structure ======
+// CHECK-HU-NEXT:  Header Unit './hu-01.h' is the Primary Module at index #1


        


More information about the cfe-commits mailing list