jansvoboda11 updated this revision to Diff 398146.
jansvoboda11 added a comment.

Rebase.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D113676/new/

https://reviews.llvm.org/D113676

Files:
  clang/include/clang/Lex/HeaderSearch.h
  clang/include/clang/Lex/ModuleMap.h
  clang/lib/Lex/HeaderSearch.cpp
  clang/lib/Lex/ModuleMap.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/test/Preprocessor/search-path-usage-modules.m
  clang/test/Preprocessor/search-path-usage.m

Index: clang/test/Preprocessor/search-path-usage.m
===================================================================
--- clang/test/Preprocessor/search-path-usage.m
+++ clang/test/Preprocessor/search-path-usage.m
@@ -128,19 +128,3 @@
 // expected-remark-re {{search path used: '{{.*}}/b-missing.hmap'}}
 #endif
 #endif
-
-// Check that search paths with module maps are reported.
-//
-// RUN: mkdir %t/modulemap_abs
-// RUN: sed "s|DIR|%/S/Inputs/search-path-usage|g"                            \
-// RUN:   %S/Inputs/search-path-usage/modulemap_abs/module.modulemap.template \
-// RUN:     > %t/modulemap_abs/module.modulemap
-// RUN: %clang_cc1 -Eonly %s -Rsearch-path-usage                           \
-// RUN:   -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/modules \
-// RUN:   -I %t/modulemap_abs                                              \
-// RUN:   -I %S/Inputs/search-path-usage/a                                 \
-// RUN:   -DMODMAP_ABS -verify
-#ifdef MODMAP_ABS
-@import b; // \
-// expected-remark-re {{search path used: '{{.*}}/modulemap_abs'}}
-#endif
Index: clang/test/Preprocessor/search-path-usage-modules.m
===================================================================
--- /dev/null
+++ clang/test/Preprocessor/search-path-usage-modules.m
@@ -0,0 +1,40 @@
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+
+// RUN: %clang_cc1 -Eonly %t/test-both.m   -I %t/sp1 -I %t/sp2 -Rsearch-path-usage \
+// RUN:   -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache 2>&1 | FileCheck %t/test-both.m
+// RUN: %clang_cc1 -Eonly %t/test-both.m   -I %t/sp2 -I %t/sp1 -Rsearch-path-usage \
+// RUN:   -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache 2>&1 | FileCheck %t/test-both.m
+
+// RUN: %clang_cc1 -Eonly %t/test-first.m  -I %t/sp2 -I %t/sp1 -Rsearch-path-usage \
+// RUN:   -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache 2>&1 | FileCheck %t/test-first.m
+// RUN: %clang_cc1 -Eonly %t/test-second.m -I %t/sp1 -I %t/sp2 -Rsearch-path-usage \
+// RUN:   -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache 2>&1 | FileCheck %t/test-second.m
+
+//--- sp1/module.modulemap
+module mod1 { header "mod1.h" }
+//--- sp1/mod1.h
+int module1();
+
+//--- sp2/module.modulemap
+module mod2 { header "mod2.h" }
+//--- sp2/mod2.h
+int module2();
+
+//--- test-both.m
+@import mod1;
+@import mod2;
+// CHECK: search path used: '{{.*}}/sp1'
+// CHECK: search path used: '{{.*}}/sp2'
+
+//--- test-first.m
+@import mod1;
+// CHECK-NOT: search path used: '{{.*}}/sp2'
+// CHECK:     search path used: '{{.*}}/sp1'
+// CHECK-NOT: search path used: '{{.*}}/sp2'
+
+//--- test-second.m
+@import mod2;
+// CHECK-NOT: search path used: '{{.*}}/sp1'
+// CHECK:     search path used: '{{.*}}/sp2'
+// CHECK-NOT: search path used: '{{.*}}/sp1'
Index: clang/lib/Serialization/ASTReader.cpp
===================================================================
--- clang/lib/Serialization/ASTReader.cpp
+++ clang/lib/Serialization/ASTReader.cpp
@@ -3907,7 +3907,7 @@
     // An implicitly-loaded module file should have its module listed in some
     // module map file that we've already loaded.
     Module *M =
-        PP.getHeaderSearchInfo().lookupModule(F.ModuleName, F.ImportLoc);
+        PP.getHeaderSearchInfo().lookupModule(F.ModuleName, SourceLocation());
     auto &Map = PP.getHeaderSearchInfo().getModuleMap();
     const FileEntry *ModMap = M ? Map.getModuleMapFileForUniquing(M) : nullptr;
     // Don't emit module relocation error if we have -fno-validate-pch
Index: clang/lib/Lex/ModuleMap.cpp
===================================================================
--- clang/lib/Lex/ModuleMap.cpp
+++ clang/lib/Lex/ModuleMap.cpp
@@ -107,8 +107,13 @@
 Module *ModuleMap::makeModule(StringRef Name, SourceLocation DefinitionLoc,
                               Module *Parent, bool IsFramework, bool IsExplicit,
                               unsigned VisibilityID) {
-  return new Module(Name, DefinitionLoc, Parent, IsFramework, IsExplicit,
-                    VisibilityID);
+  Module *Result = new Module(Name, DefinitionLoc, Parent, IsFramework,
+                              IsExplicit, VisibilityID);
+
+  for (const auto &Callback : Callbacks)
+    Callback->moduleMapModuleCreated(Result);
+
+  return Result;
 }
 
 Module::ExportDecl
Index: clang/lib/Lex/HeaderSearch.cpp
===================================================================
--- clang/lib/Lex/HeaderSearch.cpp
+++ clang/lib/Lex/HeaderSearch.cpp
@@ -36,6 +36,7 @@
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
+#include "llvm/Support/SaveAndRestore.h"
 #include "llvm/Support/VirtualFileSystem.h"
 #include <algorithm>
 #include <cassert>
@@ -85,7 +86,18 @@
                            const TargetInfo *Target)
     : HSOpts(std::move(HSOpts)), Diags(Diags),
       FileMgr(SourceMgr.getFileManager()), FrameworkMap(64),
-      ModMap(SourceMgr, Diags, LangOpts, Target, *this) {}
+      ModMap(SourceMgr, Diags, LangOpts, Target, *this) {
+  struct MMCallback : ModuleMapCallbacks {
+    HeaderSearch &HS;
+    MMCallback(HeaderSearch &HS) : HS(HS) {}
+    void moduleMapModuleCreated(Module *M) override {
+      // Module map parsing initiated by header search.
+      if (HS.CurrentSearchDir)
+        HS.ModuleToSearchDir[M] = HS.CurrentSearchDir;
+    }
+  };
+  ModMap.addModuleMapCallbacks(std::make_unique<MMCallback>(*this));
+}
 
 void HeaderSearch::PrintStats() {
   llvm::errs() << "\n*** HeaderSearch Stats:\n"
@@ -123,6 +135,7 @@
   SearchDirToHSEntry.clear();
   for (const auto &Entry : searchDirToHSEntry)
     SearchDirToHSEntry.insert({SearchDirs[Entry.first], Entry.second});
+  ModuleToSearchDir.clear();
 
   AngledDirIdx = angledDirIdx;
   SystemDirIdx = systemDirIdx;
@@ -285,8 +298,10 @@
                                    bool AllowExtraModuleMapSearch) {
   // Look in the module map to determine if there is a module by this name.
   Module *Module = ModMap.findModule(ModuleName);
-  if (Module || !AllowSearch || !HSOpts->ImplicitModuleMaps)
+  if (Module || !AllowSearch || !HSOpts->ImplicitModuleMaps) {
+    noteModuleLookupUsage(Module, ImportLoc);
     return Module;
+  }
 
   StringRef SearchName = ModuleName;
   Module = lookupModule(ModuleName, SearchName, ImportLoc,
@@ -306,6 +321,7 @@
   if (!Module && SearchName.consume_back("Private"))
     Module = lookupModule(ModuleName, SearchName, ImportLoc,
                           AllowExtraModuleMapSearch);
+  noteModuleLookupUsage(Module, ImportLoc);
   return Module;
 }
 
@@ -313,12 +329,12 @@
                                    SourceLocation ImportLoc,
                                    bool AllowExtraModuleMapSearch) {
   Module *Module = nullptr;
-  DirectoryLookup *SearchDir = nullptr;
 
   // Look through the various header search paths to load any available module
   // maps, searching for a module map that describes this module.
   for (unsigned Idx = 0; Idx != SearchDirs.size(); ++Idx) {
-    SearchDir = SearchDirs[Idx];
+    llvm::SaveAndRestore<const DirectoryLookup *> X(CurrentSearchDir,
+                                                    SearchDirs[Idx]);
 
     if (SearchDirs[Idx]->isFramework()) {
       // Search for or infer a module map for a framework. Here we use
@@ -382,9 +398,6 @@
       break;
   }
 
-  if (Module)
-    noteLookupUsage(SearchDir, ImportLoc);
-
   return Module;
 }
 
@@ -720,6 +733,12 @@
   noteLookupUsage(SearchDirs[HitIdx], Loc);
 }
 
+void HeaderSearch::noteModuleLookupUsage(Module *M, SourceLocation Loc) {
+  auto It = ModuleToSearchDir.find(M);
+  if (It != ModuleToSearchDir.end())
+    noteLookupUsage(It->second, Loc);
+}
+
 void HeaderSearch::noteLookupUsage(const DirectoryLookup *SearchDir,
                                    SourceLocation Loc) {
   UsedSearchDirs.insert(SearchDir);
@@ -1770,6 +1789,9 @@
   if (HSOpts->ImplicitModuleMaps) {
     // Load module maps for each of the header search directories.
     for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) {
+      llvm::SaveAndRestore<const DirectoryLookup *> X(CurrentSearchDir,
+                                                      SearchDirs[Idx]);
+
       bool IsSystem = SearchDirs[Idx]->isSystemHeaderDirectory();
       if (SearchDirs[Idx]->isFramework()) {
         std::error_code EC;
@@ -1822,6 +1844,9 @@
 
   // Load module maps for each of the header search directories.
   for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) {
+    llvm::SaveAndRestore<const DirectoryLookup *> X(CurrentSearchDir,
+                                                    SearchDirs[Idx]);
+
     // We only care about normal header directories.
     if (!SearchDirs[Idx]->isNormalDir())
       continue;
Index: clang/include/clang/Lex/ModuleMap.h
===================================================================
--- clang/include/clang/Lex/ModuleMap.h
+++ clang/include/clang/Lex/ModuleMap.h
@@ -70,6 +70,11 @@
   /// \param Header The umbrella header to collect.
   virtual void moduleMapAddUmbrellaHeader(FileManager *FileMgr,
                                           const FileEntry *Header) {}
+
+  /// Called when new module is created.
+  ///
+  /// \param M The newly created module.
+  virtual void moduleMapModuleCreated(Module *M) {}
 };
 
 class ModuleMap {
Index: clang/include/clang/Lex/HeaderSearch.h
===================================================================
--- clang/include/clang/Lex/HeaderSearch.h
+++ clang/include/clang/Lex/HeaderSearch.h
@@ -181,6 +181,11 @@
   llvm::DenseSet<const DirectoryLookup *> UsedSearchDirs;
   /// Mapping from SearchDir to HeaderSearchOptions::UserEntries indices.
   llvm::DenseMap<const DirectoryLookup *, unsigned> SearchDirToHSEntry;
+  /// Mapping from module to index of the search directory that discovered its
+  /// module map file.
+  llvm::DenseMap<Module *, const DirectoryLookup *> ModuleToSearchDir;
+  /// While iterating through `SearchDirs`, the current one.
+  const DirectoryLookup *CurrentSearchDir = nullptr;
 
   unsigned AngledDirIdx = 0;
   unsigned SystemDirIdx = 0;
@@ -711,6 +716,7 @@
   /// using the search path at index `HitIdx`.
   void cacheLookupSuccess(LookupFileCacheInfo &CacheLookup, unsigned HitIdx,
                           SourceLocation IncludeLoc);
+  void noteModuleLookupUsage(Module *M, SourceLocation Loc);
   /// Note that a lookup at the given include location was successful using the
   /// given search path.
   void noteLookupUsage(const DirectoryLookup *SearchDir,
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to