llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Jan Svoboda (jansvoboda11)

<details>
<summary>Changes</summary>

This PR adds new preprocessor callback that's invoked whenever the 
single-module-parse-mode skips over a module import. This will be used later on 
from the dependency scanner.

---
Full diff: https://github.com/llvm/llvm-project/pull/179714.diff


4 Files Affected:

- (modified) clang/include/clang/Lex/PPCallbacks.h (+12) 
- (modified) clang/lib/Frontend/CompilerInstance.cpp (+18) 
- (modified) clang/lib/Lex/PPDirectives.cpp (+1-6) 
- (added) clang/test/Modules/single-module-parse-mode-compiles.m (+36) 


``````````diff
diff --git a/clang/include/clang/Lex/PPCallbacks.h 
b/clang/include/clang/Lex/PPCallbacks.h
index e6120c5648798..51c6a31e143b8 100644
--- a/clang/include/clang/Lex/PPCallbacks.h
+++ b/clang/include/clang/Lex/PPCallbacks.h
@@ -212,6 +212,13 @@ class PPCallbacks {
                             const Module *Imported) {
   }
 
+  /// Callback invoked whenever a module load was skipped due to enabled
+  /// single-module-parse-mode.
+  ///
+  /// \param Skipped The module that was not loaded.
+  ///
+  virtual void moduleLoadSkipped(Module *Skipped) {}
+
   /// Callback invoked when the end of the main file is reached.
   ///
   /// No subsequent callbacks will be made.
@@ -554,6 +561,11 @@ class PPChainedCallbacks : public PPCallbacks {
     Second->moduleImport(ImportLoc, Path, Imported);
   }
 
+  void moduleLoadSkipped(Module *Skipped) override {
+    First->moduleLoadSkipped(Skipped);
+    Second->moduleLoadSkipped(Skipped);
+  }
+
   void EndOfMainFile() override {
     First->EndOfMainFile();
     Second->EndOfMainFile();
diff --git a/clang/lib/Frontend/CompilerInstance.cpp 
b/clang/lib/Frontend/CompilerInstance.cpp
index ae17e5467c712..14c50f9501beb 100644
--- a/clang/lib/Frontend/CompilerInstance.cpp
+++ b/clang/lib/Frontend/CompilerInstance.cpp
@@ -1984,6 +1984,24 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
     // * `Preprocessor::HandleHeaderIncludeOrImport` will never call this
     //   function as the `#include` or `#import` is textual.
 
+    MM.cacheModuleLoad(*Path[0].getIdentifierInfo(), Module);
+  } else if (getPreprocessorOpts().SingleModuleParseMode) {
+    // This mimics how findOrCompileModuleAndReadAST() find the module.
+    Module = getPreprocessor().getHeaderSearchInfo().lookupModule(
+        ModuleName, ImportLoc, true, !IsInclusionDirective);
+    if (Module) {
+      if (PPCallbacks *PPCb = getPreprocessor().getPPCallbacks())
+        PPCb->moduleLoadSkipped(Module);
+      // Mark the module and its submodules as if they were loaded from a PCM.
+      std::vector Worklist{Module};
+      while (!Worklist.empty()) {
+        auto *M = Worklist.back();
+        Worklist.pop_back();
+        M->IsFromModuleFile = true;
+        for (auto *SubM : M->submodules())
+          Worklist.push_back(SubM);
+      }
+    }
     MM.cacheModuleLoad(*Path[0].getIdentifierInfo(), Module);
   } else {
     SourceLocation ModuleNameEndLoc = Path.back().getLoc().getLocWithOffset(
diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp
index 8d4c9c49f756a..85edbabf09ed3 100644
--- a/clang/lib/Lex/PPDirectives.cpp
+++ b/clang/lib/Lex/PPDirectives.cpp
@@ -2494,15 +2494,10 @@ Preprocessor::ImportAction 
Preprocessor::HandleHeaderIncludeOrImport(
       (getLangOpts().CPlusPlusModules || getLangOpts().Modules) &&
       ModuleToImport && !ModuleToImport->isHeaderUnit();
 
-  if (MaybeTranslateInclude && (UsableHeaderUnit || UsableClangHeaderModule) &&
-      PPOpts.SingleModuleParseMode) {
-    Action = IncludeLimitReached;
-  }
   // Determine whether we should try to import the module for this #include, if
   // there is one. Don't do so if precompiled module support is disabled or we
   // are processing this module textually (because we're building the module).
-  else if (MaybeTranslateInclude &&
-           (UsableHeaderUnit || UsableClangHeaderModule)) {
+  if (MaybeTranslateInclude && (UsableHeaderUnit || UsableClangHeaderModule)) {
     // If this include corresponds to a module but that module is
     // unavailable, diagnose the situation and bail out.
     // FIXME: Remove this; loadModule does the same check (but produces
diff --git a/clang/test/Modules/single-module-parse-mode-compiles.m 
b/clang/test/Modules/single-module-parse-mode-compiles.m
new file mode 100644
index 0000000000000..8e9b92c86fe61
--- /dev/null
+++ b/clang/test/Modules/single-module-parse-mode-compiles.m
@@ -0,0 +1,36 @@
+// This test checks that with -fmodules-single-module-parse-mode, no modules 
get
+// compiled into PCM files from any of the import syntax Clang supports.
+
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+// RUN: mkdir %t/cache
+
+// With -fmodules-single-module-parse-mode, no modules get compiled.
+// RUN: %clang_cc1 -x objective-c -fmodules -fmodules-cache-path=%t/cache \
+// RUN:   -emit-module %t/module.modulemap -fmodule-name=Mod -o %t/Mod.pcm \
+// RUN:   -fmodules-single-module-parse-mode
+// RUN: find %t/cache -name "*.pcm" | count 0
+
+// Without -fmodules-single-module-parse-mode, loaded modules get compiled.
+// RUN: %clang_cc1 -x objective-c -fmodules -fmodules-cache-path=%t/cache \
+// RUN:   -emit-module %t/module.modulemap -fmodule-name=Mod -o %t/Mod.pcm
+// RUN: find %t/cache -name "*.pcm" | count 5
+
+//--- module.modulemap
+module Mod { header "Mod.h" }
+module Load1 { header "Load1.h" }
+module Load2 { header "Load2.h" }
+module Load3 { header "Load3.h" }
+module Load4 { header "Load4.h" }
+module Load5 { header "Load5.h" }
+//--- Mod.h
+#include "Load1.h"
+#import "Load2.h"
+@import Load3;
+#pragma clang module import Load4
+#pragma clang module load Load5
+//--- Load1.h
+//--- Load2.h
+//--- Load3.h
+//--- Load4.h
+//--- Load5.h

``````````

</details>


https://github.com/llvm/llvm-project/pull/179714
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to