[cfe-commits] r145808 - in /cfe/trunk: include/clang/Basic/Module.h include/clang/Lex/ModuleMap.h include/clang/Serialization/ASTBitCodes.h include/clang/Serialization/ASTReader.h lib/Lex/ModuleMap.cpp lib/Serialization/ASTReader.cpp lib/Serialization/ASTWriter.cpp

Douglas Gregor dgregor at apple.com
Mon Dec 5 08:33:54 PST 2011


Author: dgregor
Date: Mon Dec  5 10:33:54 2011
New Revision: 145808

URL: http://llvm.org/viewvc/llvm-project?rev=145808&view=rev
Log:
When writing a module file, keep track of the set of (sub)modules that
it imports, establishing dependencies at the (sub)module
granularity. This is not a user-visible change (yet).

Modified:
    cfe/trunk/include/clang/Basic/Module.h
    cfe/trunk/include/clang/Lex/ModuleMap.h
    cfe/trunk/include/clang/Serialization/ASTBitCodes.h
    cfe/trunk/include/clang/Serialization/ASTReader.h
    cfe/trunk/lib/Lex/ModuleMap.cpp
    cfe/trunk/lib/Serialization/ASTReader.cpp
    cfe/trunk/lib/Serialization/ASTWriter.cpp

Modified: cfe/trunk/include/clang/Basic/Module.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Module.h?rev=145808&r1=145807&r2=145808&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Module.h (original)
+++ cfe/trunk/include/clang/Basic/Module.h Mon Dec  5 10:33:54 2011
@@ -78,6 +78,10 @@
   
   ///\ brief The visibility of names within this particular module.
   NameVisibilityKind NameVisibility;
+
+  /// \brief The set of modules imported by this module, and on which this
+  /// module depends.
+  llvm::SmallVector<Module *, 2> Imports;
   
   /// \brief Describes an exported module.
   ///
@@ -89,7 +93,7 @@
   llvm::SmallVector<ExportDecl, 2> Exports;
   
   /// \brief Describes an exported module that has not yet been resolved
-  /// (perhaps because the module it refers to has not yet been loaded).
+  /// (perhaps because tASThe module it refers to has not yet been loaded).
   struct UnresolvedExportDecl {
     /// \brief The location of the 'export' keyword in the module map file.
     SourceLocation ExportLoc;

Modified: cfe/trunk/include/clang/Lex/ModuleMap.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/ModuleMap.h?rev=145808&r1=145807&r2=145808&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/ModuleMap.h (original)
+++ cfe/trunk/include/clang/Lex/ModuleMap.h Mon Dec  5 10:33:54 2011
@@ -167,6 +167,16 @@
   /// false otherwise.
   bool resolveExports(Module *Mod, bool Complain);
 
+  /// \brief Infers the (sub)module based on the given source location and 
+  /// source manager.
+  ///
+  /// \param Loc The location within the source that we are querying, along
+  /// with its source manager.
+  ///
+  /// \returns The module that owns this source location, or null if no
+  /// module owns this source location.
+  Module *inferModuleFromLocation(FullSourceLoc Loc);
+  
   /// \brief Parse the given module map file, and record any modules we 
   /// encounter.
   ///

Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=145808&r1=145807&r2=145808&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Mon Dec  5 10:33:54 2011
@@ -517,9 +517,12 @@
       SUBMODULE_HEADER = 2,
       /// \brief Metadata for submodules as a whole.
       SUBMODULE_METADATA = 3,
+      /// \brief Specifies the submodules that are imported by this 
+      /// submodule.
+      SUBMODULE_IMPORTS = 4,
       /// \brief Specifies the submodules that are re-exported from this 
       /// submodule.
-      SUBMODULE_EXPORTS = 4
+      SUBMODULE_EXPORTS = 5
     };
     
     /// \defgroup ASTAST AST file AST constants

Modified: cfe/trunk/include/clang/Serialization/ASTReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=145808&r1=145807&r2=145808&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTReader.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTReader.h Mon Dec  5 10:33:54 2011
@@ -393,21 +393,29 @@
   /// declarations in that submodule that could be made visible.
   HiddenNamesMapType HiddenNamesMap;
   
-  /// \brief A module export that hasn't yet been resolved.
-  struct UnresolvedModuleExport {
+  
+  /// \brief A module import or export that hasn't yet been resolved.
+  struct UnresolvedModuleImportExport {
     /// \brief The file in which this module resides.
     ModuleFile *File;
     
-    /// \brief The module that is exporting, along with a bit that specifies
-    /// whether this is a wildcard export.
-    llvm::PointerIntPair<Module *, 1, bool> ModuleAndWildcard;
+    /// \brief The module that is importing or exporting.
+    Module *Mod;
     
     /// \brief The local ID of the module that is being exported.
-    unsigned ExportedID;
+    unsigned ID;
+    
+    /// \brief Whether this is an import (vs. an export).
+    unsigned IsImport : 1;
+    
+    /// \brief Whether this is a wildcard export.
+    unsigned IsWildcard : 1;
   };
   
-  /// \brief The set of module exports that still need to be resolved.
-  llvm::SmallVector<UnresolvedModuleExport, 2> UnresolvedModuleExports;
+  /// \brief The set of module imports and exports that still need to be 
+  /// resolved.
+  llvm::SmallVector<UnresolvedModuleImportExport, 2> 
+    UnresolvedModuleImportExports;
   
   /// \brief A vector containing selectors that have already been loaded.
   ///

Modified: cfe/trunk/lib/Lex/ModuleMap.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/ModuleMap.cpp?rev=145808&r1=145807&r2=145808&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/ModuleMap.cpp (original)
+++ cfe/trunk/lib/Lex/ModuleMap.cpp Mon Dec  5 10:33:54 2011
@@ -238,6 +238,26 @@
   return HadError;
 }
 
+Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
+  if (Loc.isInvalid())
+    return 0;
+  
+  // Use the expansion location to determine which module we're in.
+  FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
+  if (!ExpansionLoc.isFileID())
+    return 0;  
+  
+  
+  const SourceManager &SrcMgr = Loc.getManager();
+  FileID ExpansionFileID = ExpansionLoc.getFileID();
+  const FileEntry *ExpansionFile = SrcMgr.getFileEntryForID(ExpansionFileID);
+  if (!ExpansionFile)
+    return 0;
+  
+  // Find the module that owns this header.
+  return findModuleForHeader(ExpansionFile);
+}
+
 //----------------------------------------------------------------------------//
 // Module map file parser
 //----------------------------------------------------------------------------//

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=145808&r1=145807&r2=145808&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Mon Dec  5 10:33:54 2011
@@ -2560,17 +2560,18 @@
     Id->second->setOutOfDate(true);
 
   // Resolve any unresolved module exports.
-  for (unsigned I = 0, N = UnresolvedModuleExports.size(); I != N; ++I) {
-    UnresolvedModuleExport &Unresolved = UnresolvedModuleExports[I];
-    SubmoduleID GlobalID = getGlobalSubmoduleID(*Unresolved.File,
-                                                Unresolved.ExportedID);
-    if (Module *Exported = getSubmodule(GlobalID)) {
-      Module *Exportee = Unresolved.ModuleAndWildcard.getPointer();
-      bool Wildcard = Unresolved.ModuleAndWildcard.getInt();
-      Exportee->Exports.push_back(Module::ExportDecl(Exported, Wildcard));
+  for (unsigned I = 0, N = UnresolvedModuleImportExports.size(); I != N; ++I) {
+    UnresolvedModuleImportExport &Unresolved = UnresolvedModuleImportExports[I];
+    SubmoduleID GlobalID = getGlobalSubmoduleID(*Unresolved.File,Unresolved.ID);
+    if (Module *ResolvedMod = getSubmodule(GlobalID)) {
+      if (Unresolved.IsImport)
+        Unresolved.Mod->Imports.push_back(ResolvedMod);
+      else
+        Unresolved.Mod->Exports.push_back(
+          Module::ExportDecl(ResolvedMod, Unresolved.IsWildcard));
     }
   }
-  UnresolvedModuleExports.clear();
+  UnresolvedModuleImportExports.clear();
   
   InitializeContext();
 
@@ -3097,6 +3098,27 @@
       break;
     }
         
+    case SUBMODULE_IMPORTS: {
+      if (First) {
+        Error("missing submodule metadata record at beginning of block");
+        return Failure;
+      }
+      
+      if (!CurrentModule)
+        break;
+      
+      for (unsigned Idx = 0; Idx != Record.size(); ++Idx) {
+        UnresolvedModuleImportExport Unresolved;
+        Unresolved.File = &F;
+        Unresolved.Mod = CurrentModule;
+        Unresolved.ID = Record[Idx];
+        Unresolved.IsImport = true;
+        Unresolved.IsWildcard = false;
+        UnresolvedModuleImportExports.push_back(Unresolved);
+      }
+      break;
+    }
+
     case SUBMODULE_EXPORTS: {
       if (First) {
         Error("missing submodule metadata record at beginning of block");
@@ -3107,12 +3129,13 @@
         break;
       
       for (unsigned Idx = 0; Idx + 1 < Record.size(); Idx += 2) {
-        UnresolvedModuleExport Unresolved;
+        UnresolvedModuleImportExport Unresolved;
         Unresolved.File = &F;
-        Unresolved.ModuleAndWildcard.setPointer(CurrentModule);
-        Unresolved.ModuleAndWildcard.setInt(Record[Idx + 1]);
-        Unresolved.ExportedID = Record[Idx];
-        UnresolvedModuleExports.push_back(Unresolved);
+        Unresolved.Mod = CurrentModule;
+        Unresolved.ID = Record[Idx];
+        Unresolved.IsImport = false;
+        Unresolved.IsWildcard = Record[Idx + 1];
+        UnresolvedModuleImportExports.push_back(Unresolved);
       }
       
       // Once we've loaded the set of exports, there's no reason to keep 

Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=145808&r1=145807&r2=145808&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Mon Dec  5 10:33:54 2011
@@ -1858,6 +1858,22 @@
 }
 
 void ASTWriter::WriteSubmodules(Module *WritingModule) {
+  // 
+  // FIXME: This feels like it belongs somewhere else, but there are no
+  // other consumers of this information.
+  SourceManager &SrcMgr = PP->getSourceManager();
+  ModuleMap &ModMap = PP->getHeaderSearchInfo().getModuleMap();
+  for (ASTContext::import_iterator I = Context->local_import_begin(),
+                                IEnd = Context->local_import_end();
+       I != IEnd; ++I) {
+    assert(SubmoduleIDs.find(I->getImportedModule()) != SubmoduleIDs.end());
+    if (Module *ImportedFrom
+          = ModMap.inferModuleFromLocation(FullSourceLoc(I->getLocation(), 
+                                                         SrcMgr))) {
+      ImportedFrom->Imports.push_back(I->getImportedModule());
+    }
+  }
+  
   // Enter the submodule description block.
   Stream.EnterSubblock(SUBMODULE_BLOCK_ID, NUM_ALLOWED_ABBREVS_SIZE);
   
@@ -1924,7 +1940,18 @@
       Stream.EmitRecordWithBlob(HeaderAbbrev, Record, 
                                 Mod->Headers[I]->getName());
     }
-    
+
+    // Emit the imports. 
+    if (!Mod->Imports.empty()) {
+      Record.clear();
+      for (unsigned I = 0, N = Mod->Imports.size(); I != N; ++I) {
+        unsigned ImportedID = SubmoduleIDs[Mod->Imports[I]];
+        assert(ImportedID && "Unknown submodule!");                                           
+        Record.push_back(ImportedID);
+      }
+      Stream.EmitRecord(SUBMODULE_IMPORTS, Record);
+    }
+
     // Emit the exports. 
     if (!Mod->Exports.empty()) {
       Record.clear();
@@ -1960,22 +1987,11 @@
 ASTWriter::inferSubmoduleIDFromLocation(SourceLocation Loc) {
   if (Loc.isInvalid() || SubmoduleIDs.empty())
     return 0; // No submodule
-  
-  // Use the expansion location to determine which module we're in.
-  SourceManager &SrcMgr = PP->getSourceManager();
-  SourceLocation ExpansionLoc = SrcMgr.getExpansionLoc(Loc);
-  if (!ExpansionLoc.isFileID())
-    return 0;  
-
-  
-  FileID ExpansionFileID = SrcMgr.getFileID(ExpansionLoc);
-  const FileEntry *ExpansionFile = SrcMgr.getFileEntryForID(ExpansionFileID);
-  if (!ExpansionFile)
-    return 0;
-  
-  // Find the module that owns this header.
+    
+  // Find the module that owns this location.
   ModuleMap &ModMap = PP->getHeaderSearchInfo().getModuleMap();
-  Module *OwningMod = ModMap.findModuleForHeader(ExpansionFile);
+  Module *OwningMod 
+    = ModMap.inferModuleFromLocation(FullSourceLoc(Loc,PP->getSourceManager()));
   if (!OwningMod)
     return 0;
   





More information about the cfe-commits mailing list