<div dir="ltr"><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Mar 17, 2015 at 6:42 PM, Richard Smith <span dir="ltr"><<a href="mailto:richard-llvm@metafoo.co.uk" target="_blank">richard-llvm@metafoo.co.uk</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: rsmith<br>
Date: Tue Mar 17 20:42:29 2015<br>
New Revision: 232583<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=232583&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=232583&view=rev</a><br>
Log:<br>
Make module files passed to a module build via -fmodule-file= available to<br>
consumers of that module.<br>
<br>
Previously, such a file would only be available if the module happened to<br>
actually import something from that module.<br>
<br>
Added:<br>
    cfe/trunk/test/Modules/Inputs/explicit-build/d.h<br>
Modified:<br>
    cfe/trunk/include/clang/Serialization/ASTBitCodes.h<br>
    cfe/trunk/include/clang/Serialization/ModuleManager.h<br>
    cfe/trunk/lib/Frontend/CompilerInstance.cpp<br>
    cfe/trunk/lib/Serialization/ASTReader.cpp<br>
    cfe/trunk/lib/Serialization/ASTWriter.cpp<br>
    cfe/trunk/lib/Serialization/ModuleManager.cpp<br>
    cfe/trunk/test/Modules/Inputs/explicit-build/module.modulemap<br>
    cfe/trunk/test/Modules/explicit-build.cpp<br>
<br>
Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=232583&r1=232582&r2=232583&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=232583&r1=232582&r2=232583&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)<br>
+++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Tue Mar 17 20:42:29 2015<br>
@@ -295,6 +295,10 @@ namespace clang {<br>
<br>
       /// \brief Record code for the module build directory.<br>
       MODULE_DIRECTORY = 16,<br>
+<br>
+      /// \brief Record code for the list of other AST files made available by<br>
+      /// this AST file but not actually used by it.<br>
+      KNOWN_MODULE_FILES = 17,<br>
     };<br>
<br>
     /// \brief Record types that occur within the input-files block<br>
<br>
Modified: cfe/trunk/include/clang/Serialization/ModuleManager.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ModuleManager.h?rev=232583&r1=232582&r2=232583&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ModuleManager.h?rev=232583&r1=232582&r2=232583&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Serialization/ModuleManager.h (original)<br>
+++ cfe/trunk/include/clang/Serialization/ModuleManager.h Tue Mar 17 20:42:29 2015<br>
@@ -35,7 +35,13 @@ class ModuleManager {<br>
<br>
   /// \brief All loaded modules, indexed by name.<br>
   llvm::DenseMap<const FileEntry *, ModuleFile *> Modules;<br>
-<br>
+<br>
+  typedef llvm::SetVector<const FileEntry *> AdditionalKnownModuleFileSet;<br>
+<br>
+  /// \brief Additional module files that are known but not loaded. Tracked<br>
+  /// here so that we can re-export them if necessary.<br>
+  AdditionalKnownModuleFileSet AdditionalKnownModuleFiles;<br>
+<br>
   /// \brief FileManager that handles translating between filenames and<br>
   /// FileEntry *.<br>
   FileManager &FileMgr;<br>
@@ -219,6 +225,19 @@ public:<br>
   /// has been "accepted", and will not (can not) be unloaded.<br>
   void moduleFileAccepted(ModuleFile *MF);<br>
<br>
+  /// \brief Notification from the frontend that the given module file is<br>
+  /// part of this compilation (even if not imported) and, if this compilation<br>
+  /// is exported, should be made available to importers of it.<br>
+  bool addKnownModuleFile(StringRef FileName);<br>
+<br>
+  /// \brief Get a list of additional module files that are not currently<br>
+  /// loaded but are considered to be part of the current compilation.<br>
+  llvm::iterator_range<AdditionalKnownModuleFileSet::const_iterator><br>
+  getAdditionalKnownModuleFiles() {<br>
+    return llvm::make_range(AdditionalKnownModuleFiles.begin(),<br>
+                            AdditionalKnownModuleFiles.end());<br>
+  }<br>
+<br>
   /// \brief Visit each of the modules.<br>
   ///<br>
   /// This routine visits each of the modules, starting with the<br>
<br>
Modified: cfe/trunk/lib/Frontend/CompilerInstance.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInstance.cpp?rev=232583&r1=232582&r2=232583&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInstance.cpp?rev=232583&r1=232582&r2=232583&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Frontend/CompilerInstance.cpp (original)<br>
+++ cfe/trunk/lib/Frontend/CompilerInstance.cpp Tue Mar 17 20:42:29 2015<br>
@@ -1331,6 +1331,19 @@ bool CompilerInstance::loadModuleFile(St<br>
     }<br>
   } RMN(*this);<br>
<br>
+  // If we don't already have an ASTReader, create one now.<br>
+  if (!ModuleManager)<br>
+    createModuleManager();<br>
+<br>
+  // Tell the module manager about this module file.<br>
+  if (getModuleManager()->getModuleManager().addKnownModuleFile(FileName)) {<br>
+    getDiagnostics().Report(SourceLocation(), diag::err_module_file_not_found)<br>
+      << FileName;<br>
+    return false;<br>
+  }<br>
+<br>
+  // Build our mapping of module names to module files from this file<br>
+  // and its imports.<br>
   RMN.visitImport(FileName);<br>
<br>
   if (RMN.Failed)<br>
<br>
Modified: cfe/trunk/lib/Serialization/ASTReader.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=232583&r1=232582&r2=232583&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=232583&r1=232582&r2=232583&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)<br>
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Tue Mar 17 20:42:29 2015<br>
@@ -2462,6 +2462,9 @@ ASTReader::ReadControlBlock(ModuleFile &<br>
       break;<br>
     }<br>
<br>
+    case KNOWN_MODULE_FILES:<br>
+      break;<br>
+<br>
     case LANGUAGE_OPTIONS: {<br>
       bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch) == 0;<br>
       // FIXME: The &F == *ModuleMgr.begin() check is wrong for modules.<br>
@@ -4248,6 +4251,8 @@ bool ASTReader::readASTFileControlBlock(<br>
                                         FileManager &FileMgr,<br>
                                         ASTReaderListener &Listener) {<br>
   // Open the AST file.<br>
+  // FIXME: This allows use of the VFS; we do not allow use of the<br>
+  // VFS when actually loading a module.<br>
   auto Buffer = FileMgr.getBufferForFile(Filename);<br>
   if (!Buffer) {<br>
     return true;<br>
@@ -4418,6 +4423,20 @@ bool ASTReader::readASTFileControlBlock(<br>
       break;<br>
     }<br>
<br>
+    case KNOWN_MODULE_FILES: {<br>
+      // Known-but-not-technically-used module files are treated as imports.<br>
+      if (!NeedsImports)<br>
+        break;<br>
+<br>
+      unsigned Idx = 0, N = Record.size();<br>
+      while (Idx < N) {<br>
+        std::string Filename = ReadString(Record, Idx);<br>
+        ResolveImportedPath(Filename, ModuleDir);<br>
+        Listener.visitImport(Filename);<br>
+      }<br>
+      break;<br>
+    }<br>
+<br>
     default:<br>
       // No other validation to perform.<br>
       break;<br>
@@ -6842,6 +6861,9 @@ void ASTReader::StartTranslationUnit(AST<br>
   EagerlyDeserializedDecls.clear();<br>
<br>
   PassInterestingDeclsToConsumer();<br>
+<br>
+  if (DeserializationListener)<br>
+    DeserializationListener->ReaderInitialized(this);<br>
 }<br>
<br>
 void ASTReader::PrintStats() {<br>
<br>
Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=232583&r1=232582&r2=232583&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=232583&r1=232582&r2=232583&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)<br>
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Tue Mar 17 20:42:29 2015<br>
@@ -867,6 +867,7 @@ void ASTWriter::WriteBlockInfoBlock() {<br>
   RECORD(MODULE_NAME);<br>
   RECORD(MODULE_MAP_FILE);<br>
   RECORD(IMPORTS);<br>
+  RECORD(KNOWN_MODULE_FILES);<br>
   RECORD(LANGUAGE_OPTIONS);<br>
   RECORD(TARGET_OPTIONS);<br>
   RECORD(ORIGINAL_FILE);<br>
@@ -1222,20 +1223,28 @@ void ASTWriter::WriteControlBlock(Prepro<br>
     serialization::ModuleManager &Mgr = Chain->getModuleManager();<br>
     Record.clear();<br>
<br>
-    for (ModuleManager::ModuleIterator M = Mgr.begin(), MEnd = Mgr.end();<br>
-         M != MEnd; ++M) {<br>
+    for (auto *M : Mgr) {<br>
       // Skip modules that weren't directly imported.<br>
-      if (!(*M)->isDirectlyImported())<br>
+      if (!M->isDirectlyImported())<br>
         continue;<br>
<br>
-      Record.push_back((unsigned)(*M)->Kind); // FIXME: Stable encoding<br>
-      AddSourceLocation((*M)->ImportLoc, Record);<br>
-      Record.push_back((*M)->File->getSize());<br>
-      Record.push_back((*M)->File->getModificationTime());<br>
-      Record.push_back((*M)->Signature);<br>
-      AddPath((*M)->FileName, Record);<br>
+      Record.push_back((unsigned)M->Kind); // FIXME: Stable encoding<br>
+      AddSourceLocation(M->ImportLoc, Record);<br>
+      Record.push_back(M->File->getSize());<br>
+      Record.push_back(M->File->getModificationTime());<br>
+      Record.push_back(M->Signature);<br>
+      AddPath(M->FileName, Record);<br>
     }<br>
     Stream.EmitRecord(IMPORTS, Record);<br>
+<br>
+    // Also emit a list of known module files that were not imported,<br>
+    // but are made available by this module.<br>
+    // FIXME: Should we also include a signature here?<br>
+    Record.clear();<br>
+    for (auto *E : Mgr.getAdditionalKnownModuleFiles())<br>
+      AddPath(E->getName(), Record);<br>
+    if (!Record.empty())<br>
+      Stream.EmitRecord(KNOWN_MODULE_FILES, Record);<br>
   }<br>
<br>
   // Language options.<br>
@@ -5655,6 +5664,8 @@ void ASTWriter::ReaderInitialized(ASTRea<br>
<br>
   Chain = Reader;<br>
<br>
+  // Note, this will get called multiple times, once one the reader starts up<br>
+  // and again each time it's done reading a PCH or module.<br>
   FirstDeclID = NUM_PREDEF_DECL_IDS + Chain->getTotalNumDecls();<br>
   FirstTypeID = NUM_PREDEF_TYPE_IDS + Chain->getTotalNumTypes();<br>
   FirstIdentID = NUM_PREDEF_IDENT_IDS + Chain->getTotalNumIdentifiers();<br>
<br>
Modified: cfe/trunk/lib/Serialization/ModuleManager.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ModuleManager.cpp?rev=232583&r1=232582&r2=232583&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ModuleManager.cpp?rev=232583&r1=232582&r2=232583&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Serialization/ModuleManager.cpp (original)<br>
+++ cfe/trunk/lib/Serialization/ModuleManager.cpp Tue Mar 17 20:42:29 2015<br>
@@ -227,6 +227,15 @@ ModuleManager::addInMemoryBuffer(StringR<br>
   InMemoryBuffers[Entry] = std::move(Buffer);<br>
 }<br>
<br>
+bool ModuleManager::addKnownModuleFile(StringRef FileName) {<br>
+  const FileEntry *File;<br>
+  if (lookupModuleFile(FileName, 0, 0, File))<br>
+    return true;<br>
+  if (!Modules.count(File))<br>
+    AdditionalKnownModuleFiles.insert(File);<br>
+  return false;<br>
+}<br>
+<br>
 ModuleManager::VisitState *ModuleManager::allocateVisitState() {<br>
   // Fast path: if we have a cached state, use it.<br>
   if (FirstVisitState) {<br>
@@ -263,6 +272,8 @@ void ModuleManager::setGlobalIndex(Globa<br>
 }<br>
<br>
 void ModuleManager::moduleFileAccepted(ModuleFile *MF) {<br>
+  AdditionalKnownModuleFiles.remove(MF->File);<br>
+<br>
   if (!GlobalIndex || GlobalIndex->loadedModuleFile(MF))<br>
     return;<br>
<br>
<br>
Added: cfe/trunk/test/Modules/Inputs/explicit-build/d.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/explicit-build/d.h?rev=232583&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/explicit-build/d.h?rev=232583&view=auto</a><br>
==============================================================================<br>
    (empty)<br>
<br>
Modified: cfe/trunk/test/Modules/Inputs/explicit-build/module.modulemap<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/explicit-build/module.modulemap?rev=232583&r1=232582&r2=232583&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/explicit-build/module.modulemap?rev=232583&r1=232582&r2=232583&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/Modules/Inputs/explicit-build/module.modulemap (original)<br>
+++ cfe/trunk/test/Modules/Inputs/explicit-build/module.modulemap Tue Mar 17 20:42:29 2015<br>
@@ -1,3 +1,4 @@<br>
 module a { header "a.h" }<br>
 module b { header "b.h" export * }<br>
 module c { header "c.h" export * }<br>
+module d { header "d.h" }<br>
<br>
Modified: cfe/trunk/test/Modules/explicit-build.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/explicit-build.cpp?rev=232583&r1=232582&r2=232583&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/explicit-build.cpp?rev=232583&r1=232582&r2=232583&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/Modules/explicit-build.cpp (original)<br>
+++ cfe/trunk/test/Modules/explicit-build.cpp Tue Mar 17 20:42:29 2015<br>
@@ -64,6 +64,19 @@<br>
 // RUN:            -fmodule-file=%t/c.pcm \<br>
 // RUN:            -verify %s -DHAVE_A -DHAVE_B -DHAVE_C<br>
<br>
+// -------------------------------<br>
+// Check that -fmodule-file= in a module build makes the file transitively<br>
+// available even if it's not used.<br>
+// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fno-implicit-modules -Rmodule-build -fno-modules-error-recovery \<br>
+// RUN:            -fmodule-file=%t/b.pcm \<br>
+// RUN:            -fmodule-name=d -emit-module %S/Inputs/explicit-build/module.modulemap -o %t/d.pcm \<br>
+// RUN:            2>&1 | FileCheck --check-prefix=CHECK-NO-IMPLICIT-BUILD %s --allow-empty<br>
+//<br>
+// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fno-implicit-modules -Rmodule-build -fno-modules-error-recovery \<br>
+// RUN:            -I%S/Inputs/explicit-build \<br>
+// RUN:            -fmodule-file=%t/d.pcm \<br>
+// RUN:            -verify %s -DHAVE_A -DHAVE_B<br></blockquote><div><br></div><div>^^</div><div>Do you need to add -fmodules-cache-path=%t to this invocation?</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br>
 #if HAVE_A<br>
   #include "a.h"<br>
   static_assert(a == 1, "");<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature"><div dir="ltr">Alexey Samsonov<br><a href="mailto:vonosmas@gmail.com" target="_blank">vonosmas@gmail.com</a></div></div>
</div></div>