]> granicus.if.org Git - clang/commitdiff
OnDiskHashTable: Make the iterable version separate.
authorJustin Bogner <mail@justinbogner.com>
Mon, 14 Apr 2014 16:34:29 +0000 (16:34 +0000)
committerJustin Bogner <mail@justinbogner.com>
Mon, 14 Apr 2014 16:34:29 +0000 (16:34 +0000)
Currently the on disk hash table's key_iterator and data_iterator make
the assumption that the table data starts exactly four bytes after the
base of the table. This happens to be true for all of the tables we
currently iterate over, but not for all of the OnDiskHashTables we
currently use. For example, key_ and data_iterator would iterate over
meaningless data if they were used on the hash tables in PTHLexer.

We make the API safer by breaking this into two types. One doesn't
have the iterators, and the other must be told where the payload
starts.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@206189 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/OnDiskHashTable.h
include/clang/Serialization/ASTReader.h
include/clang/Serialization/Module.h
lib/Serialization/ASTReader.cpp
lib/Serialization/ASTReaderInternals.h
lib/Serialization/GlobalModuleIndex.cpp

index f9ac613f28d852312f8539f31dfb7d68408d25ba..1a9a96abe836e58da3e19261495c4f5897e10a01 100644 (file)
@@ -266,6 +266,41 @@ public:
 
   iterator end() const { return iterator(); }
 
+  Info &getInfoObj() { return InfoObj; }
+
+  static OnDiskChainedHashTable* Create(const unsigned char* Buckets,
+                                        const unsigned char* const Base,
+                                        const Info &InfoObj = Info()) {
+    using namespace llvm::support;
+    assert(Buckets > Base);
+    assert((reinterpret_cast<uintptr_t>(Buckets) & 0x3) == 0 &&
+           "buckets should be 4-byte aligned.");
+
+    unsigned NumBuckets = endian::readNext<uint32_t, little, aligned>(Buckets);
+    unsigned NumEntries = endian::readNext<uint32_t, little, aligned>(Buckets);
+    return new OnDiskChainedHashTable<Info>(NumBuckets, NumEntries, Buckets,
+                                            Base, InfoObj);
+  }
+};
+
+template<typename Info>
+class OnDiskIterableChainedHashTable : public OnDiskChainedHashTable<Info> {
+  const unsigned char *Payload;
+
+public:
+  typedef OnDiskChainedHashTable<Info>          base_type;
+  typedef typename base_type::internal_key_type internal_key_type;
+  typedef typename base_type::external_key_type external_key_type;
+  typedef typename base_type::data_type         data_type;
+
+  OnDiskIterableChainedHashTable(unsigned NumBuckets, unsigned NumEntries,
+                                 const unsigned char *Buckets,
+                                 const unsigned char *Payload,
+                                 const unsigned char *Base,
+                                 const Info &InfoObj = Info())
+      : base_type(NumBuckets, NumEntries, Buckets, Base, InfoObj),
+        Payload(Payload) {}
+
   /// \brief Iterates over all of the keys in the table.
   class key_iterator {
     const unsigned char *Ptr;
@@ -329,7 +364,7 @@ public:
   };
 
   key_iterator key_begin() {
-    return key_iterator(Base + 4, getNumEntries(), &InfoObj);
+    return key_iterator(Payload, this->getNumEntries(), &this->getInfoObj());
   }
   key_iterator key_end() { return key_iterator(); }
 
@@ -396,15 +431,13 @@ public:
   };
 
   data_iterator data_begin() {
-    return data_iterator(Base + 4, getNumEntries(), &InfoObj);
+    return data_iterator(Payload, this->getNumEntries(), &this->getInfoObj());
   }
   data_iterator data_end() { return data_iterator(); }
 
-  Info &getInfoObj() { return InfoObj; }
-
-  static OnDiskChainedHashTable *Create(const unsigned char *Buckets,
-                                        const unsigned char *const Base,
-                                        const Info &InfoObj = Info()) {
+  static OnDiskIterableChainedHashTable *
+  Create(const unsigned char *Buckets, const unsigned char *const Payload,
+         const unsigned char *const Base, const Info &InfoObj = Info()) {
     using namespace llvm::support;
     assert(Buckets > Base);
     assert((reinterpret_cast<uintptr_t>(Buckets) & 0x3) == 0 &&
@@ -412,8 +445,8 @@ public:
 
     unsigned NumBuckets = endian::readNext<uint32_t, little, aligned>(Buckets);
     unsigned NumEntries = endian::readNext<uint32_t, little, aligned>(Buckets);
-    return new OnDiskChainedHashTable<Info>(NumBuckets, NumEntries, Buckets,
-                                            Base, InfoObj);
+    return new OnDiskIterableChainedHashTable<Info>(
+        NumBuckets, NumEntries, Buckets, Payload, Base, InfoObj);
   }
 };
 
index b19991a6ea8303062b12ebc07ae57b1b45db27e1..54002aa52a63fa652161fee086c1ef65667135e5 100644 (file)
@@ -254,7 +254,7 @@ class ReadMethodPoolVisitor;
 namespace reader {
   class ASTIdentifierLookupTrait;
   /// \brief The on-disk hash table used for the DeclContext's Name lookup table.
-  typedef OnDiskChainedHashTable<ASTDeclContextNameLookupTrait>
+  typedef OnDiskIterableChainedHashTable<ASTDeclContextNameLookupTrait>
     ASTDeclContextNameLookupTable;
 }
 
index 469785de7c45e2dbe11cc9ffe061fedfc280b1b3..626901ed79fecfb914303663f7d955928c0d84ba 100644 (file)
@@ -29,6 +29,7 @@ class FileEntry;
 class DeclContext;
 class Module;
 template<typename Info> class OnDiskChainedHashTable;
+template<typename Info> class OnDiskIterableChainedHashTable;
 
 namespace serialization {
 
@@ -49,7 +50,7 @@ struct DeclContextInfo {
   DeclContextInfo()
     : NameLookupTableData(), LexicalDecls(), NumLexicalDecls() {}
 
-  OnDiskChainedHashTable<reader::ASTDeclContextNameLookupTrait>
+  OnDiskIterableChainedHashTable<reader::ASTDeclContextNameLookupTrait>
     *NameLookupTableData; // an ASTDeclContextNameLookupTable.
   const KindDeclIDPair *LexicalDecls;
   unsigned NumLexicalDecls;
index 18768353c1c40c552b6180155336d98856f037df..1d1957d6bfe7d24aa0cc41d103e991ccab55bafe 100644 (file)
@@ -851,11 +851,11 @@ bool ASTReader::ReadDeclContextStorage(ModuleFile &M,
       Error("Expected visible lookup table block");
       return true;
     }
-    Info.NameLookupTableData
-      = ASTDeclContextNameLookupTable::Create(
-                    (const unsigned char *)Blob.data() + Record[0],
-                    (const unsigned char *)Blob.data(),
-                    ASTDeclContextNameLookupTrait(*this, M));
+    Info.NameLookupTableData = ASTDeclContextNameLookupTable::Create(
+        (const unsigned char *)Blob.data() + Record[0],
+        (const unsigned char *)Blob.data() + sizeof(uint32_t),
+        (const unsigned char *)Blob.data(),
+        ASTDeclContextNameLookupTrait(*this, M));
   }
 
   return false;
@@ -2509,10 +2509,11 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
       unsigned Idx = 0;
       serialization::DeclID ID = ReadDeclID(F, Record, Idx);
       ASTDeclContextNameLookupTable *Table =
-        ASTDeclContextNameLookupTable::Create(
-                        (const unsigned char *)Blob.data() + Record[Idx++],
-                        (const unsigned char *)Blob.data(),
-                        ASTDeclContextNameLookupTrait(*this, F));
+          ASTDeclContextNameLookupTable::Create(
+              (const unsigned char *)Blob.data() + Record[Idx++],
+              (const unsigned char *)Blob.data() + sizeof(uint32_t),
+              (const unsigned char *)Blob.data(),
+              ASTDeclContextNameLookupTrait(*this, F));
       if (ID == PREDEF_DECL_TRANSLATION_UNIT_ID) { // Is it the TU?
         DeclContext *TU = Context.getTranslationUnitDecl();
         F.DeclContextInfos[TU].NameLookupTableData = Table;
@@ -2531,11 +2532,11 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
     case IDENTIFIER_TABLE:
       F.IdentifierTableData = Blob.data();
       if (Record[0]) {
-        F.IdentifierLookupTable
-          = ASTIdentifierLookupTable::Create(
-                       (const unsigned char *)F.IdentifierTableData + Record[0],
-                       (const unsigned char *)F.IdentifierTableData,
-                       ASTIdentifierLookupTrait(*this, F));
+        F.IdentifierLookupTable = ASTIdentifierLookupTable::Create(
+            (const unsigned char *)F.IdentifierTableData + Record[0],
+            (const unsigned char *)F.IdentifierTableData + sizeof(uint32_t),
+            (const unsigned char *)F.IdentifierTableData,
+            ASTIdentifierLookupTrait(*this, F));
         
         PP.getIdentifierTable().setExternalIdentifierLookup(this);
       }
index 9149b18480f96685016ec42a52af7e0586b232db..fd328926eb3e208dd59d973b93061e4854fe267c 100644 (file)
@@ -140,7 +140,7 @@ public:
   
 /// \brief The on-disk hash table used to contain information about
 /// all of the identifiers in the program.
-typedef OnDiskChainedHashTable<ASTIdentifierLookupTrait>
+typedef OnDiskIterableChainedHashTable<ASTIdentifierLookupTrait>
   ASTIdentifierLookupTable;
 
 /// \brief Class that performs lookup for a selector's entries in the global
index 14b149f078c693af19be216d0e79b7690cddb601..804a14363a88a247eb69da03a57141c2c2e6d3f6 100644 (file)
@@ -114,7 +114,8 @@ public:
   }
 };
 
-typedef OnDiskChainedHashTable<IdentifierIndexReaderTrait> IdentifierIndexTable;
+typedef OnDiskIterableChainedHashTable<IdentifierIndexReaderTrait>
+    IdentifierIndexTable;
 
 }
 
@@ -210,9 +211,9 @@ GlobalModuleIndex::GlobalModuleIndex(llvm::MemoryBuffer *Buffer,
       // Wire up the identifier index.
       if (Record[0]) {
         IdentifierIndex = IdentifierIndexTable::Create(
-                            (const unsigned char *)Blob.data() + Record[0],
-                            (const unsigned char *)Blob.data(),
-                            IdentifierIndexReaderTrait());
+            (const unsigned char *)Blob.data() + Record[0],
+            (const unsigned char *)Blob.data() + sizeof(uint32_t),
+            (const unsigned char *)Blob.data(), IdentifierIndexReaderTrait());
       }
       break;
     }
@@ -591,11 +592,13 @@ bool GlobalModuleIndexBuilder::loadModuleFile(const FileEntry *File) {
 
     // Handle the identifier table
     if (State == ASTBlock && Code == IDENTIFIER_TABLE && Record[0] > 0) {
-      typedef OnDiskChainedHashTable<InterestingASTIdentifierLookupTrait>
-        InterestingIdentifierTable;
+      typedef
+          OnDiskIterableChainedHashTable<InterestingASTIdentifierLookupTrait>
+          InterestingIdentifierTable;
       std::unique_ptr<InterestingIdentifierTable> Table(
           InterestingIdentifierTable::Create(
               (const unsigned char *)Blob.data() + Record[0],
+              (const unsigned char *)Blob.data() + sizeof(uint32_t),
               (const unsigned char *)Blob.data()));
       for (InterestingIdentifierTable::data_iterator D = Table->data_begin(),
                                                      DEnd = Table->data_end();