OnDiskHashTable: Make the iterable version separate.
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. llvm-svn: 206189
This commit is contained in:
parent
8c1f0818c0
commit
da4e650e5c
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue