r232583 - Make module files passed to a module build via -fmodule-file= available to

Richard Smith richard-llvm at metafoo.co.uk
Tue Mar 17 18:42:30 PDT 2015


Author: rsmith
Date: Tue Mar 17 20:42:29 2015
New Revision: 232583

URL: http://llvm.org/viewvc/llvm-project?rev=232583&view=rev
Log:
Make module files passed to a module build via -fmodule-file= available to
consumers of that module.

Previously, such a file would only be available if the module happened to
actually import something from that module.

Added:
    cfe/trunk/test/Modules/Inputs/explicit-build/d.h
Modified:
    cfe/trunk/include/clang/Serialization/ASTBitCodes.h
    cfe/trunk/include/clang/Serialization/ModuleManager.h
    cfe/trunk/lib/Frontend/CompilerInstance.cpp
    cfe/trunk/lib/Serialization/ASTReader.cpp
    cfe/trunk/lib/Serialization/ASTWriter.cpp
    cfe/trunk/lib/Serialization/ModuleManager.cpp
    cfe/trunk/test/Modules/Inputs/explicit-build/module.modulemap
    cfe/trunk/test/Modules/explicit-build.cpp

Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=232583&r1=232582&r2=232583&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Tue Mar 17 20:42:29 2015
@@ -295,6 +295,10 @@ namespace clang {
 
       /// \brief Record code for the module build directory.
       MODULE_DIRECTORY = 16,
+
+      /// \brief Record code for the list of other AST files made available by
+      /// this AST file but not actually used by it.
+      KNOWN_MODULE_FILES = 17,
     };
 
     /// \brief Record types that occur within the input-files block

Modified: cfe/trunk/include/clang/Serialization/ModuleManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ModuleManager.h?rev=232583&r1=232582&r2=232583&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ModuleManager.h (original)
+++ cfe/trunk/include/clang/Serialization/ModuleManager.h Tue Mar 17 20:42:29 2015
@@ -35,7 +35,13 @@ class ModuleManager {
   
   /// \brief All loaded modules, indexed by name.
   llvm::DenseMap<const FileEntry *, ModuleFile *> Modules;
-  
+
+  typedef llvm::SetVector<const FileEntry *> AdditionalKnownModuleFileSet;
+
+  /// \brief Additional module files that are known but not loaded. Tracked
+  /// here so that we can re-export them if necessary.
+  AdditionalKnownModuleFileSet AdditionalKnownModuleFiles;
+
   /// \brief FileManager that handles translating between filenames and
   /// FileEntry *.
   FileManager &FileMgr;
@@ -219,6 +225,19 @@ public:
   /// has been "accepted", and will not (can not) be unloaded.
   void moduleFileAccepted(ModuleFile *MF);
 
+  /// \brief Notification from the frontend that the given module file is
+  /// part of this compilation (even if not imported) and, if this compilation
+  /// is exported, should be made available to importers of it.
+  bool addKnownModuleFile(StringRef FileName);
+
+  /// \brief Get a list of additional module files that are not currently
+  /// loaded but are considered to be part of the current compilation.
+  llvm::iterator_range<AdditionalKnownModuleFileSet::const_iterator>
+  getAdditionalKnownModuleFiles() {
+    return llvm::make_range(AdditionalKnownModuleFiles.begin(),
+                            AdditionalKnownModuleFiles.end());
+  }
+
   /// \brief Visit each of the modules.
   ///
   /// This routine visits each of the modules, starting with the

Modified: cfe/trunk/lib/Frontend/CompilerInstance.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInstance.cpp?rev=232583&r1=232582&r2=232583&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CompilerInstance.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInstance.cpp Tue Mar 17 20:42:29 2015
@@ -1331,6 +1331,19 @@ bool CompilerInstance::loadModuleFile(St
     }
   } RMN(*this);
 
+  // If we don't already have an ASTReader, create one now.
+  if (!ModuleManager)
+    createModuleManager();
+
+  // Tell the module manager about this module file.
+  if (getModuleManager()->getModuleManager().addKnownModuleFile(FileName)) {
+    getDiagnostics().Report(SourceLocation(), diag::err_module_file_not_found)
+      << FileName;
+    return false;
+  }
+
+  // Build our mapping of module names to module files from this file
+  // and its imports.
   RMN.visitImport(FileName);
 
   if (RMN.Failed)

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=232583&r1=232582&r2=232583&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Tue Mar 17 20:42:29 2015
@@ -2462,6 +2462,9 @@ ASTReader::ReadControlBlock(ModuleFile &
       break;
     }
 
+    case KNOWN_MODULE_FILES:
+      break;
+
     case LANGUAGE_OPTIONS: {
       bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch) == 0;
       // FIXME: The &F == *ModuleMgr.begin() check is wrong for modules.
@@ -4248,6 +4251,8 @@ bool ASTReader::readASTFileControlBlock(
                                         FileManager &FileMgr,
                                         ASTReaderListener &Listener) {
   // Open the AST file.
+  // FIXME: This allows use of the VFS; we do not allow use of the
+  // VFS when actually loading a module.
   auto Buffer = FileMgr.getBufferForFile(Filename);
   if (!Buffer) {
     return true;
@@ -4418,6 +4423,20 @@ bool ASTReader::readASTFileControlBlock(
       break;
     }
 
+    case KNOWN_MODULE_FILES: {
+      // Known-but-not-technically-used module files are treated as imports.
+      if (!NeedsImports)
+        break;
+
+      unsigned Idx = 0, N = Record.size();
+      while (Idx < N) {
+        std::string Filename = ReadString(Record, Idx);
+        ResolveImportedPath(Filename, ModuleDir);
+        Listener.visitImport(Filename);
+      }
+      break;
+    }
+
     default:
       // No other validation to perform.
       break;
@@ -6842,6 +6861,9 @@ void ASTReader::StartTranslationUnit(AST
   EagerlyDeserializedDecls.clear();
 
   PassInterestingDeclsToConsumer();
+
+  if (DeserializationListener)
+    DeserializationListener->ReaderInitialized(this);
 }
 
 void ASTReader::PrintStats() {

Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=232583&r1=232582&r2=232583&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Tue Mar 17 20:42:29 2015
@@ -867,6 +867,7 @@ void ASTWriter::WriteBlockInfoBlock() {
   RECORD(MODULE_NAME);
   RECORD(MODULE_MAP_FILE);
   RECORD(IMPORTS);
+  RECORD(KNOWN_MODULE_FILES);
   RECORD(LANGUAGE_OPTIONS);
   RECORD(TARGET_OPTIONS);
   RECORD(ORIGINAL_FILE);
@@ -1222,20 +1223,28 @@ void ASTWriter::WriteControlBlock(Prepro
     serialization::ModuleManager &Mgr = Chain->getModuleManager();
     Record.clear();
 
-    for (ModuleManager::ModuleIterator M = Mgr.begin(), MEnd = Mgr.end();
-         M != MEnd; ++M) {
+    for (auto *M : Mgr) {
       // Skip modules that weren't directly imported.
-      if (!(*M)->isDirectlyImported())
+      if (!M->isDirectlyImported())
         continue;
 
-      Record.push_back((unsigned)(*M)->Kind); // FIXME: Stable encoding
-      AddSourceLocation((*M)->ImportLoc, Record);
-      Record.push_back((*M)->File->getSize());
-      Record.push_back((*M)->File->getModificationTime());
-      Record.push_back((*M)->Signature);
-      AddPath((*M)->FileName, Record);
+      Record.push_back((unsigned)M->Kind); // FIXME: Stable encoding
+      AddSourceLocation(M->ImportLoc, Record);
+      Record.push_back(M->File->getSize());
+      Record.push_back(M->File->getModificationTime());
+      Record.push_back(M->Signature);
+      AddPath(M->FileName, Record);
     }
     Stream.EmitRecord(IMPORTS, Record);
+
+    // Also emit a list of known module files that were not imported,
+    // but are made available by this module.
+    // FIXME: Should we also include a signature here?
+    Record.clear();
+    for (auto *E : Mgr.getAdditionalKnownModuleFiles())
+      AddPath(E->getName(), Record);
+    if (!Record.empty())
+      Stream.EmitRecord(KNOWN_MODULE_FILES, Record);
   }
 
   // Language options.
@@ -5655,6 +5664,8 @@ void ASTWriter::ReaderInitialized(ASTRea
 
   Chain = Reader;
 
+  // Note, this will get called multiple times, once one the reader starts up
+  // and again each time it's done reading a PCH or module.
   FirstDeclID = NUM_PREDEF_DECL_IDS + Chain->getTotalNumDecls();
   FirstTypeID = NUM_PREDEF_TYPE_IDS + Chain->getTotalNumTypes();
   FirstIdentID = NUM_PREDEF_IDENT_IDS + Chain->getTotalNumIdentifiers();

Modified: cfe/trunk/lib/Serialization/ModuleManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ModuleManager.cpp?rev=232583&r1=232582&r2=232583&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ModuleManager.cpp (original)
+++ cfe/trunk/lib/Serialization/ModuleManager.cpp Tue Mar 17 20:42:29 2015
@@ -227,6 +227,15 @@ ModuleManager::addInMemoryBuffer(StringR
   InMemoryBuffers[Entry] = std::move(Buffer);
 }
 
+bool ModuleManager::addKnownModuleFile(StringRef FileName) {
+  const FileEntry *File;
+  if (lookupModuleFile(FileName, 0, 0, File))
+    return true;
+  if (!Modules.count(File))
+    AdditionalKnownModuleFiles.insert(File);
+  return false;
+}
+
 ModuleManager::VisitState *ModuleManager::allocateVisitState() {
   // Fast path: if we have a cached state, use it.
   if (FirstVisitState) {
@@ -263,6 +272,8 @@ void ModuleManager::setGlobalIndex(Globa
 }
 
 void ModuleManager::moduleFileAccepted(ModuleFile *MF) {
+  AdditionalKnownModuleFiles.remove(MF->File);
+
   if (!GlobalIndex || GlobalIndex->loadedModuleFile(MF))
     return;
 

Added: cfe/trunk/test/Modules/Inputs/explicit-build/d.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/explicit-build/d.h?rev=232583&view=auto
==============================================================================
    (empty)

Modified: cfe/trunk/test/Modules/Inputs/explicit-build/module.modulemap
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/explicit-build/module.modulemap?rev=232583&r1=232582&r2=232583&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/explicit-build/module.modulemap (original)
+++ cfe/trunk/test/Modules/Inputs/explicit-build/module.modulemap Tue Mar 17 20:42:29 2015
@@ -1,3 +1,4 @@
 module a { header "a.h" }
 module b { header "b.h" export * }
 module c { header "c.h" export * }
+module d { header "d.h" }

Modified: cfe/trunk/test/Modules/explicit-build.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/explicit-build.cpp?rev=232583&r1=232582&r2=232583&view=diff
==============================================================================
--- cfe/trunk/test/Modules/explicit-build.cpp (original)
+++ cfe/trunk/test/Modules/explicit-build.cpp Tue Mar 17 20:42:29 2015
@@ -64,6 +64,19 @@
 // RUN:            -fmodule-file=%t/c.pcm \
 // RUN:            -verify %s -DHAVE_A -DHAVE_B -DHAVE_C
 
+// -------------------------------
+// Check that -fmodule-file= in a module build makes the file transitively
+// available even if it's not used.
+// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fno-implicit-modules -Rmodule-build -fno-modules-error-recovery \
+// RUN:            -fmodule-file=%t/b.pcm \
+// RUN:            -fmodule-name=d -emit-module %S/Inputs/explicit-build/module.modulemap -o %t/d.pcm \
+// RUN:            2>&1 | FileCheck --check-prefix=CHECK-NO-IMPLICIT-BUILD %s --allow-empty
+//
+// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fno-implicit-modules -Rmodule-build -fno-modules-error-recovery \
+// RUN:            -I%S/Inputs/explicit-build \
+// RUN:            -fmodule-file=%t/d.pcm \
+// RUN:            -verify %s -DHAVE_A -DHAVE_B
+
 #if HAVE_A
   #include "a.h"
   static_assert(a == 1, "");





More information about the cfe-commits mailing list