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

Douglas Gregor dgregor at apple.com
Wed Nov 30 16:59:37 PST 2011


Author: dgregor
Date: Wed Nov 30 18:59:36 2011
New Revision: 145549

URL: http://llvm.org/viewvc/llvm-project?rev=145549&view=rev
Log:
Switch the ID numbers used for submodule IDs in the AST reader over to
a standard global/local scheme, so that submodule definitions will
eventually be able to refer to submodules in other top-level
modules. We'll need this functionality soonish.

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

Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=145549&r1=145548&r2=145549&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Wed Nov 30 18:59:36 2011
@@ -127,7 +127,7 @@
     /// \brief The number of predefined identifier IDs.
     const unsigned int NUM_PREDEF_IDENT_IDS = 1;
     
-    /// \brief An ID number that refers to an ObjC selctor in an AST file.
+    /// \brief An ID number that refers to an ObjC selector in an AST file.
     typedef uint32_t SelectorID;
 
     /// \brief The number of predefined selector IDs.
@@ -141,6 +141,12 @@
     /// preprocessing record.
     typedef uint32_t PreprocessedEntityID;
 
+    /// \brief An ID number that refers to a submodule in a module file.
+    typedef uint32_t SubmoduleID;
+    
+    /// \brief The number of predefined submodule IDs.
+    const unsigned int NUM_PREDEF_SUBMODULE_IDS = 1;
+
     /// \brief Source range/offset of a preprocessed entity.
     struct PPEntityOffset {
       /// \brief Raw source location of beginning of range.
@@ -504,7 +510,9 @@
       /// if any.
       SUBMODULE_UMBRELLA = 1,
       /// \brief Specifies a header that falls into this (sub)module.
-      SUBMODULE_HEADER = 2
+      SUBMODULE_HEADER = 2,
+      /// \brief Metadata for submodules as a whole.
+      SUBMODULE_METADATA = 3
     };
     
     /// \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=145549&r1=145548&r2=145549&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTReader.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTReader.h Wed Nov 30 18:59:36 2011
@@ -369,6 +369,20 @@
   /// global identifier ID to produce a local ID.
   GlobalIdentifierMapType GlobalIdentifierMap;
 
+  /// \brief A vector containing submodules that have already been loaded.
+  ///
+  /// This vector is indexed by the Submodule ID (-1). NULL submodule entries
+  /// indicate that the particular submodule ID has not yet been loaded.
+  SmallVector<Module *, 2> SubmodulesLoaded;
+  
+  typedef ContinuousRangeMap<serialization::SubmoduleID, ModuleFile *, 4>
+    GlobalSubmoduleMapType;
+  
+  /// \brief Mapping from global submodule IDs to the module file in which the
+  /// submodule resides along with the offset that should be added to the
+  /// global submodule ID to produce a local ID.
+  GlobalSubmoduleMapType GlobalSubmoduleMap;
+
   /// \brief A vector containing selectors that have already been loaded.
   ///
   /// This vector is indexed by the Selector ID (-1). NULL selector
@@ -866,6 +880,11 @@
     return static_cast<unsigned>(DeclsLoaded.size());
   }
 
+  /// \brief Returns the number of submodules known.
+  unsigned getTotalNumSubmodules() const {
+    return static_cast<unsigned>(SubmodulesLoaded.size());
+  }
+  
   /// \brief Returns the number of selectors found in the chain.
   unsigned getTotalNumSelectors() const {
     return static_cast<unsigned>(SelectorsLoaded.size());
@@ -1146,6 +1165,15 @@
   /// \brief Read the source location entry with index ID.
   virtual bool ReadSLocEntry(int ID);
 
+  /// \brief Retrieve the global submodule ID given a module and its local ID
+  /// number.
+  serialization::SubmoduleID 
+  getGlobalSubmoduleID(ModuleFile &M, unsigned LocalID);
+  
+  /// \brief Retrieve the submodule that corresponds to a global submodule ID.
+  ///
+  Module *getSubmodule(serialization::SubmoduleID GlobalID);
+  
   /// \brief Retrieve a selector from the given module with its local ID
   /// number.
   Selector getLocalSelector(ModuleFile &M, unsigned LocalID);

Modified: cfe/trunk/include/clang/Serialization/ASTWriter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTWriter.h?rev=145549&r1=145548&r2=145549&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTWriter.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTWriter.h Wed Nov 30 18:59:36 2011
@@ -204,10 +204,16 @@
   /// table.
   std::vector<uint32_t> IdentifierOffsets;
 
+  /// \brief The first ID number we can use for our own submodules.
+  serialization::SubmoduleID FirstSubmoduleID;
+  
+  /// \brief The submodule ID that will be assigned to the next new submodule.
+  serialization::SubmoduleID NextSubmoduleID;
+
   /// \brief The first ID number we can use for our own selectors.
   serialization::SelectorID FirstSelectorID;
 
-  /// \brief The selector ID that will be assigned to the next new identifier.
+  /// \brief The selector ID that will be assigned to the next new selector.
   serialization::SelectorID NextSelectorID;
 
   /// \brief Map that provides the ID numbers of each Selector.

Modified: cfe/trunk/include/clang/Serialization/Module.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/Module.h?rev=145549&r1=145548&r2=145549&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/Module.h (original)
+++ cfe/trunk/include/clang/Serialization/Module.h Wed Nov 30 18:59:36 2011
@@ -201,8 +201,15 @@
   /// search information.
   const char *HeaderFileFrameworkStrings;
 
-  // === Submodule information ===
-  llvm::SmallVector<Module *, 2> Submodules;
+  // === Submodule information ===  
+  /// \brief The number of submodules in this module.
+  unsigned LocalNumSubmodules;
+  
+  /// \brief Base submodule ID for submodules local to this module.
+  serialization::SubmoduleID BaseSubmoduleID;
+  
+  /// \brief Remapping table for submodule IDs in this module.
+  ContinuousRangeMap<uint32_t, int, 2> SubmoduleRemap;
   
   // === Selectors ===
 

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=145549&r1=145548&r2=145549&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Wed Nov 30 18:59:36 2011
@@ -2062,6 +2062,8 @@
       ContinuousRangeMap<uint32_t, int, 2>::Builder 
         PreprocessedEntityRemap(F.PreprocessedEntityRemap);
       ContinuousRangeMap<uint32_t, int, 2>::Builder 
+        SubmoduleRemap(F.SubmoduleRemap);
+      ContinuousRangeMap<uint32_t, int, 2>::Builder 
         SelectorRemap(F.SelectorRemap);
       ContinuousRangeMap<uint32_t, int, 2>::Builder DeclRemap(F.DeclRemap);
       ContinuousRangeMap<uint32_t, int, 2>::Builder TypeRemap(F.TypeRemap);
@@ -2079,6 +2081,7 @@
         uint32_t SLocOffset = io::ReadUnalignedLE32(Data);
         uint32_t IdentifierIDOffset = io::ReadUnalignedLE32(Data);
         uint32_t PreprocessedEntityIDOffset = io::ReadUnalignedLE32(Data);
+        uint32_t SubmoduleIDOffset = io::ReadUnalignedLE32(Data);
         uint32_t SelectorIDOffset = io::ReadUnalignedLE32(Data);
         uint32_t DeclIDOffset = io::ReadUnalignedLE32(Data);
         uint32_t TypeIndexOffset = io::ReadUnalignedLE32(Data);
@@ -2092,6 +2095,8 @@
         PreprocessedEntityRemap.insert(
           std::make_pair(PreprocessedEntityIDOffset, 
             OM->BasePreprocessedEntityID - PreprocessedEntityIDOffset));
+        SubmoduleRemap.insert(std::make_pair(SubmoduleIDOffset, 
+                                      OM->BaseSubmoduleID - SubmoduleIDOffset));
         SelectorRemap.insert(std::make_pair(SelectorIDOffset, 
                                OM->BaseSelectorID - SelectorIDOffset));
         DeclRemap.insert(std::make_pair(DeclIDOffset, 
@@ -2828,8 +2833,10 @@
   }
 
   ModuleMap &ModMap = PP.getHeaderSearchInfo().getModuleMap();
+  bool First = true;
   Module *CurrentModule = 0;
   RecordData Record;
+  SubmoduleID CurrentModuleGlobalIndex = 0;
   while (true) {
     unsigned Code = F.Stream.ReadCode();
     if (Code == llvm::bitc::END_BLOCK) {
@@ -2864,31 +2871,41 @@
       break;
       
     case SUBMODULE_DEFINITION: {
+      if (First) {
+        Error("missing submodule metadata record at beginning of block");
+        return Failure;
+      }
+
       StringRef Name(BlobStart, BlobLen);
-      unsigned Parent = Record[0];
+      unsigned Parent = getGlobalSubmoduleID(F, Record[0]);
       bool IsFramework = Record[1];
       bool IsExplicit = Record[2];
 
       Module *ParentModule = 0;
-      if (Parent) {
-        if (Parent > F.Submodules.size()) {
-          Error("malformed submodule parent entry");
-          return Failure;
-        }
-        
-        ParentModule = F.Submodules[Parent - 1];
-      } 
+      if (Parent)
+        ParentModule = getSubmodule(Parent);
       
       // Retrieve this (sub)module from the module map, creating it if
       // necessary.
       CurrentModule = ModMap.findOrCreateModule(Name, ParentModule, 
                                                 IsFramework, 
                                                 IsExplicit).first;
-      F.Submodules.push_back(CurrentModule);
+      
+      if (CurrentModuleGlobalIndex >= SubmodulesLoaded.size() ||
+          SubmodulesLoaded[CurrentModuleGlobalIndex]) {
+        Error("too many submodules");
+        return Failure;
+      }
+      SubmodulesLoaded[CurrentModuleGlobalIndex++] = CurrentModule;
       break;
     }
         
     case SUBMODULE_UMBRELLA: {
+      if (First) {
+        Error("missing submodule metadata record at beginning of block");
+        return Failure;
+      }
+
       if (!CurrentModule)
         break;
       
@@ -2905,6 +2922,11 @@
     }
         
     case SUBMODULE_HEADER: {
+      if (First) {
+        Error("missing submodule metadata record at beginning of block");
+        return Failure;
+      }
+
       if (!CurrentModule)
         break;
       
@@ -2918,6 +2940,33 @@
       }
       break;      
     }
+        
+    case SUBMODULE_METADATA: {
+      if (!First) {
+        Error("submodule metadata record not at beginning of block");
+        return Failure;
+      }
+      First = false;
+      
+      F.BaseSubmoduleID = getTotalNumSubmodules();
+      CurrentModuleGlobalIndex = F.BaseSubmoduleID;
+      F.LocalNumSubmodules = Record[0];
+      unsigned LocalBaseSubmoduleID = Record[1];
+      if (F.LocalNumSubmodules > 0) {
+        // Introduce the global -> local mapping for submodules within this 
+        // module.
+        GlobalSubmoduleMap.insert(std::make_pair(getTotalNumSubmodules()+1,&F));
+        
+        // Introduce the local -> global mapping for submodules within this 
+        // module.
+        F.SubmoduleRemap.insert(
+          std::make_pair(LocalBaseSubmoduleID,
+                         F.BaseSubmoduleID - LocalBaseSubmoduleID));
+        
+        SubmodulesLoaded.resize(SubmodulesLoaded.size() + F.LocalNumSubmodules);
+      }      
+      break;
+    }
     }
   }
 
@@ -4652,6 +4701,7 @@
   dumpModuleIDMap("Global type map", GlobalTypeMap);
   dumpModuleIDMap("Global declaration map", GlobalDeclMap);
   dumpModuleIDMap("Global identifier map", GlobalIdentifierMap);
+  dumpModuleIDMap("Global submodule map", GlobalSubmoduleMap);
   dumpModuleIDMap("Global selector map", GlobalSelectorMap);
   dumpModuleIDMap("Global preprocessed entity map", 
                   GlobalPreprocessedEntityMap);
@@ -5120,6 +5170,33 @@
   return ReadSLocEntryRecord(ID) != Success;
 }
 
+serialization::SubmoduleID
+ASTReader::getGlobalSubmoduleID(ModuleFile &M, unsigned LocalID) {
+  if (LocalID < NUM_PREDEF_SUBMODULE_IDS)
+    return LocalID;
+  
+  ContinuousRangeMap<uint32_t, int, 2>::iterator I
+    = M.SubmoduleRemap.find(LocalID - NUM_PREDEF_SUBMODULE_IDS);
+  assert(I != M.SubmoduleRemap.end() 
+         && "Invalid index into identifier index remap");
+  
+  return LocalID + I->second;
+}
+
+Module *ASTReader::getSubmodule(SubmoduleID GlobalID) {
+  if (GlobalID < NUM_PREDEF_SUBMODULE_IDS) {
+    assert(GlobalID == 0 && "Unhandled global submodule ID");
+    return 0;
+  }
+  
+  if (GlobalID > SubmodulesLoaded.size()) {
+    Error("submodule ID out of range in AST file");
+    return 0;
+  }
+  
+  return SubmodulesLoaded[GlobalID - NUM_PREDEF_SUBMODULE_IDS];
+}
+                               
 Selector ASTReader::getLocalSelector(ModuleFile &M, unsigned LocalID) {
   return DecodeSelector(getGlobalSelectorID(M, LocalID));
 }

Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=145549&r1=145548&r2=145549&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Wed Nov 30 18:59:36 2011
@@ -1845,6 +1845,18 @@
   }
 }
 
+/// \brief Compute the number of modules within the given tree (including the
+/// given module).
+static unsigned getNumberOfModules(Module *Mod) {
+  unsigned ChildModules = 0;
+  for (llvm::StringMap<Module *>::iterator Sub = Mod->SubModules.begin(),
+                                        SubEnd = Mod->SubModules.end();
+       Sub != SubEnd; ++Sub)
+    ChildModules += getNumberOfModules(Sub->getValue());
+  
+  return ChildModules + 1;
+}
+
 void ASTWriter::WriteSubmodules(Module *WritingModule) {
   // Enter the submodule description block.
   Stream.EnterSubblock(SUBMODULE_BLOCK_ID, NUM_ALLOWED_ABBREVS_SIZE);
@@ -1868,16 +1880,20 @@
   Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_HEADER));
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
   unsigned HeaderAbbrev = Stream.EmitAbbrev(Abbrev);
-
+  
+  // Write the submodule metadata block.
+  RecordData Record;
+  Record.push_back(getNumberOfModules(WritingModule));
+  Record.push_back(FirstSubmoduleID - NUM_PREDEF_SUBMODULE_IDS);
+  Stream.EmitRecord(SUBMODULE_METADATA, Record);
+  
   // Write all of the submodules.
-  unsigned SubmoduleID = 1;
   std::queue<Module *> Q;
   Q.push(WritingModule);
-  RecordData Record;
   while (!Q.empty()) {
     Module *Mod = Q.front();
     Q.pop();
-    SubmoduleIDs[Mod] = SubmoduleID++;
+    SubmoduleIDs[Mod] = NextSubmoduleID++;
     
     // Emit the definition of the block.
     Record.clear();
@@ -2850,6 +2866,8 @@
     FirstDeclID(NUM_PREDEF_DECL_IDS), NextDeclID(FirstDeclID),
     FirstTypeID(NUM_PREDEF_TYPE_IDS), NextTypeID(FirstTypeID),
     FirstIdentID(NUM_PREDEF_IDENT_IDS), NextIdentID(FirstIdentID), 
+    FirstSubmoduleID(NUM_PREDEF_SUBMODULE_IDS), 
+    NextSubmoduleID(FirstSubmoduleID),
     FirstSelectorID(NUM_PREDEF_SELECTOR_IDS), NextSelectorID(FirstSelectorID),
     CollectedStmts(&StmtsToEmit),
     NumStatements(0), NumMacros(0), NumLexicalDeclContexts(0),
@@ -3137,6 +3155,7 @@
     //   identifier-id:i32
     //   preprocessed-entity-id:i32
     //   macro-definition-id:i32
+    //   submodule-id:i32
     //   selector-id:i32
     //   declaration-id:i32
     //   c++-base-specifiers-id:i32
@@ -3158,6 +3177,7 @@
         io::Emit32(Out, (*M)->SLocEntryBaseOffset);
         io::Emit32(Out, (*M)->BaseIdentifierID);
         io::Emit32(Out, (*M)->BasePreprocessedEntityID);
+        io::Emit32(Out, (*M)->BaseSubmoduleID);
         io::Emit32(Out, (*M)->BaseSelectorID);
         io::Emit32(Out, (*M)->BaseDeclID);
         io::Emit32(Out, (*M)->BaseTypeIndex);
@@ -4055,6 +4075,7 @@
   assert(FirstDeclID == NextDeclID &&
          FirstTypeID == NextTypeID &&
          FirstIdentID == NextIdentID &&
+         FirstSubmoduleID == NextSubmoduleID &&
          FirstSelectorID == NextSelectorID &&
          "Setting chain after writing has started.");
 
@@ -4063,11 +4084,13 @@
   FirstDeclID = NUM_PREDEF_DECL_IDS + Chain->getTotalNumDecls();
   FirstTypeID = NUM_PREDEF_TYPE_IDS + Chain->getTotalNumTypes();
   FirstIdentID = NUM_PREDEF_IDENT_IDS + Chain->getTotalNumIdentifiers();
+  FirstSubmoduleID = NUM_PREDEF_SUBMODULE_IDS + Chain->getTotalNumSubmodules();
   FirstSelectorID = NUM_PREDEF_SELECTOR_IDS + Chain->getTotalNumSelectors();
   NextDeclID = FirstDeclID;
   NextTypeID = FirstTypeID;
   NextIdentID = FirstIdentID;
   NextSelectorID = FirstSelectorID;
+  NextSubmoduleID = FirstSubmoduleID;
 }
 
 void ASTWriter::IdentifierRead(IdentID ID, IdentifierInfo *II) {

Modified: cfe/trunk/lib/Serialization/Module.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/Module.cpp?rev=145549&r1=145548&r2=145549&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/Module.cpp (original)
+++ cfe/trunk/lib/Serialization/Module.cpp Wed Nov 30 18:59:36 2011
@@ -30,7 +30,7 @@
     PreprocessedEntityOffsets(0), NumPreprocessedEntities(0),
     LocalNumHeaderFileInfos(0), 
     HeaderFileInfoTableData(0), HeaderFileInfoTable(0),
-    HeaderFileFrameworkStrings(0),
+    HeaderFileFrameworkStrings(0), LocalNumSubmodules(0),
     LocalNumSelectors(0), SelectorOffsets(0), BaseSelectorID(0),
     SelectorLookupTableData(0), SelectorLookupTable(0), LocalNumDecls(0),
     DeclOffsets(0), BaseDeclID(0),
@@ -88,7 +88,11 @@
   llvm::errs() << "  Base identifier ID: " << BaseIdentifierID << '\n'
                << "  Number of identifiers: " << LocalNumIdentifiers << '\n';
   dumpLocalRemap("Identifier ID local -> global map", IdentifierRemap);
-  
+
+  llvm::errs() << "  Base submodule ID: " << BaseSubmoduleID << '\n'
+               << "  Number of submodules: " << LocalNumSubmodules << '\n';
+  dumpLocalRemap("Submodule ID local -> global map", SubmoduleRemap);
+
   llvm::errs() << "  Base selector ID: " << BaseSelectorID << '\n'
                << "  Number of selectors: " << LocalNumSelectors << '\n';
   dumpLocalRemap("Selector ID local -> global map", SelectorRemap);





More information about the cfe-commits mailing list