diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-04-11 00:14:32 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-04-11 00:14:32 +0000 |
commit | afaf308b779cd8e8fc8c42601b9f383423c15c2d (patch) | |
tree | e64fdbb060c1731b7e9f717425201d845b37a454 /lib/Frontend/PCHWriter.cpp | |
parent | 1670e403c48f3af4fceff3f6773a0e1cfc6c4eb3 (diff) |
Store unique IDs for identifiers in the PCH file. Use some bitmangling
so that we only need to perform the lookup and identifier resolution
once per identifier in the PCH file.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68846 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Frontend/PCHWriter.cpp')
-rw-r--r-- | lib/Frontend/PCHWriter.cpp | 65 |
1 files changed, 60 insertions, 5 deletions
diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp index 4963ea1160..3c795bf722 100644 --- a/lib/Frontend/PCHWriter.cpp +++ b/lib/Frontend/PCHWriter.cpp @@ -818,6 +818,55 @@ void PCHWriter::WriteDeclsBlock(ASTContext &Context) { S.ExitBlock(); } +/// \brief Write the identifier table into the PCH file. +/// +/// The identifier table consists of a blob containing string data +/// (the actual identifiers themselves) and a separate "offsets" index +/// that maps identifier IDs to locations within the blob. +void PCHWriter::WriteIdentifierTable() { + using namespace llvm; + + // Create and write out the blob that contains the identifier + // strings. + RecordData IdentOffsets; + IdentOffsets.resize(IdentifierIDs.size()); + { + // Create the identifier string data. + std::vector<char> Data; + Data.push_back(0); // Data must not be empty. + for (llvm::DenseMap<const IdentifierInfo *, pch::IdentID>::iterator + ID = IdentifierIDs.begin(), IDEnd = IdentifierIDs.end(); + ID != IDEnd; ++ID) { + assert(ID->first && "NULL identifier in identifier table"); + + // Make sure we're starting on an odd byte. The PCH reader + // expects the low bit to be set on all of the offsets. + if ((Data.size() & 0x01) == 0) + Data.push_back((char)0); + + IdentOffsets[ID->second - 1] = Data.size(); + Data.insert(Data.end(), + ID->first->getName(), + ID->first->getName() + ID->first->getLength()); + Data.push_back((char)0); + } + + // Create a blob abbreviation + BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); + Abbrev->Add(BitCodeAbbrevOp(pch::IDENTIFIER_TABLE)); + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Triple name + unsigned IDTableAbbrev = S.EmitAbbrev(Abbrev); + + // Write the identifier table + RecordData Record; + Record.push_back(pch::IDENTIFIER_TABLE); + S.EmitRecordWithBlob(IDTableAbbrev, Record, &Data.front(), Data.size()); + } + + // Write the offsets table for identifier IDs. + S.EmitRecord(pch::IDENTIFIER_OFFSET, IdentOffsets); +} + PCHWriter::PCHWriter(llvm::BitstreamWriter &S) : S(S), NextTypeID(pch::NUM_PREDEF_TYPE_IDS) { } @@ -842,6 +891,7 @@ void PCHWriter::WritePCH(ASTContext &Context, const Preprocessor &PP) { WriteDeclsBlock(Context); S.EmitRecord(pch::TYPE_OFFSET, TypeOffsets); S.EmitRecord(pch::DECL_OFFSET, DeclOffsets); + WriteIdentifierTable(); S.ExitBlock(); } @@ -858,11 +908,16 @@ void PCHWriter::AddAPInt(const llvm::APInt &Value, RecordData &Record) { } void PCHWriter::AddIdentifierRef(const IdentifierInfo *II, RecordData &Record) { - // FIXME: Emit an identifier ID, not the actual string! - const char *Name = II->getName(); - unsigned Len = strlen(Name); - Record.push_back(Len); - Record.insert(Record.end(), Name, Name + Len); + if (II == 0) { + Record.push_back(0); + return; + } + + pch::IdentID &ID = IdentifierIDs[II]; + if (ID == 0) + ID = IdentifierIDs.size(); + + Record.push_back(ID); } void PCHWriter::AddTypeRef(QualType T, RecordData &Record) { |