This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rGb45888e959ad: [clang][modules] Report module maps affecting 
`no_undeclared_includes` modules (authored by jansvoboda11).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D120464

Files:
  clang/include/clang/Basic/Module.h
  clang/lib/Basic/Module.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/test/Modules/add-remove-irrelevant-module-map.m

Index: clang/test/Modules/add-remove-irrelevant-module-map.m
===================================================================
--- clang/test/Modules/add-remove-irrelevant-module-map.m
+++ clang/test/Modules/add-remove-irrelevant-module-map.m
@@ -25,6 +25,34 @@
 
 // Neither PCM file considers 'b.modulemap' an input:
 //
-// RUN: %clang_cc1 -module-file-info %t/cache-without-b/a.pcm | FileCheck %s
-// RUN: %clang_cc1 -module-file-info %t/cache-with-b/a.pcm | FileCheck %s
-// CHECK-NOT: Input file: {{.*}}/b.modulemap
+// RUN: %clang_cc1 -module-file-info %t/cache-without-b/a.pcm | FileCheck %s --check-prefix=CHECK-B
+// RUN: %clang_cc1 -module-file-info %t/cache-with-b/a.pcm | FileCheck %s --check-prefix=CHECK-B
+// CHECK-B-NOT: Input file: {{.*}}/b.modulemap
+
+//--- c.modulemap
+module c [no_undeclared_includes] { header "c.h" }
+
+//--- c.h
+#if __has_include("d.h") // This should use 'd.modulemap' in order to determine that 'd.h'
+                         // doesn't exist for 'c' because of its '[no_undeclared_includes]'.
+#endif
+
+//--- d.modulemap
+module d { header "d.h" }
+
+//--- d.h
+// empty
+
+//--- test-no-undeclared-includes.m
+// expected-no-diagnostics
+@import c;
+
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t/cache -fdisable-module-hash \
+// RUN:   -fmodule-map-file=%t/c.modulemap -fmodule-map-file=%t/d.modulemap \
+// RUN:   %t/test-no-undeclared-includes.m -verify
+
+// The PCM file considers 'd.modulemap' an input because it affects the compilation,
+// although it doesn't describe the built module or its imports.
+//
+// RUN: %clang_cc1 -module-file-info %t/cache/c.pcm | FileCheck %s --check-prefix=CHECK-D -DDIR=%t
+// CHECK-D: Input file: [[DIR]]/d.modulemap
Index: clang/lib/Serialization/ASTWriter.cpp
===================================================================
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -164,8 +164,8 @@
 std::set<const FileEntry *> GetAllModuleMaps(const HeaderSearch &HS,
                                              Module *RootModule) {
   std::set<const FileEntry *> ModuleMaps{};
-  std::set<Module *> ProcessedModules;
-  SmallVector<Module *> ModulesToProcess{RootModule};
+  std::set<const Module *> ProcessedModules;
+  SmallVector<const Module *> ModulesToProcess{RootModule};
 
   SmallVector<const FileEntry *, 16> FilesByUID;
   HS.getFileMgr().GetUniqueIDMapping(FilesByUID);
@@ -209,6 +209,11 @@
       }
       ModulesToProcess.push_back(ImportedModule);
     }
+
+    for (const Module *UndeclaredModule : CurrentModule->UndeclaredUses)
+      if (UndeclaredModule &&
+          ProcessedModules.find(UndeclaredModule) == ProcessedModules.end())
+        ModulesToProcess.push_back(UndeclaredModule);
   }
 
   return ModuleMaps;
@@ -2861,6 +2866,8 @@
     // Might be unnecessary as use declarations are only used to build the
     // module itself.
 
+    // TODO: Consider serializing undeclared uses of modules.
+
     // Emit the link libraries.
     for (const auto &LL : Mod->LinkLibraries) {
       RecordData::value_type Record[] = {SUBMODULE_LINK_LIBRARY,
Index: clang/lib/Basic/Module.cpp
===================================================================
--- clang/lib/Basic/Module.cpp
+++ clang/lib/Basic/Module.cpp
@@ -267,7 +267,7 @@
   return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end());
 }
 
-bool Module::directlyUses(const Module *Requested) const {
+bool Module::directlyUses(const Module *Requested) {
   auto *Top = getTopLevelModule();
 
   // A top-level module implicitly uses itself.
@@ -282,6 +282,9 @@
   if (!Requested->Parent && Requested->Name == "_Builtin_stddef_max_align_t")
     return true;
 
+  if (NoUndeclaredIncludes)
+    UndeclaredUses.insert(Requested);
+
   return false;
 }
 
Index: clang/include/clang/Basic/Module.h
===================================================================
--- clang/include/clang/Basic/Module.h
+++ clang/include/clang/Basic/Module.h
@@ -371,6 +371,10 @@
   /// The set of use declarations that have yet to be resolved.
   SmallVector<ModuleId, 2> UnresolvedDirectUses;
 
+  /// When \c NoUndeclaredIncludes is true, the set of modules this module tried
+  /// to import but didn't because they are not direct uses.
+  llvm::SmallSetVector<const Module *, 2> UndeclaredUses;
+
   /// A library or framework to link against when an entity from this
   /// module is used.
   struct LinkLibrary {
@@ -601,7 +605,7 @@
 
   /// Determine whether this module has declared its intention to
   /// directly use another module.
-  bool directlyUses(const Module *Requested) const;
+  bool directlyUses(const Module *Requested);
 
   /// Add the given feature requirement to the list of features
   /// required by this module.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to