diff options
Diffstat (limited to 'lib/Frontend')
-rw-r--r-- | lib/Frontend/PCHReader.cpp | 46 | ||||
-rw-r--r-- | lib/Frontend/PCHWriter.cpp | 65 |
2 files changed, 98 insertions, 13 deletions
diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp index 345e673b47..b21beed307 100644 --- a/lib/Frontend/PCHReader.cpp +++ b/lib/Frontend/PCHReader.cpp @@ -477,7 +477,7 @@ PCHReader::PCHReadResult PCHReader::ReadPCHBlock() { return IgnorePCH; break; - case pch::TARGET_TRIPLE: + case pch::TARGET_TRIPLE: { std::string TargetTriple(BlobStart, BlobLen); if (TargetTriple != Context.Target.getTargetTriple()) { Diag(diag::warn_pch_target_triple) @@ -487,6 +487,27 @@ PCHReader::PCHReadResult PCHReader::ReadPCHBlock() { } break; } + + case pch::IDENTIFIER_TABLE: + IdentifierTable = BlobStart; + break; + + case pch::IDENTIFIER_OFFSET: + if (!IdentifierData.empty()) { + Error("Duplicate IDENTIFIER_OFFSET record in PCH file"); + return Failure; + } + IdentifierData.swap(Record); +#ifndef NDEBUG + for (unsigned I = 0, N = IdentifierData.size(); I != N; ++I) { + if ((IdentifierData[I] & 0x01) == 0) { + Error("Malformed identifier table in the precompiled header"); + return Failure; + } + } +#endif + break; + } } Error("Premature end of bitstream"); @@ -927,13 +948,22 @@ void PCHReader::PrintStats() { const IdentifierInfo *PCHReader::GetIdentifierInfo(const RecordData &Record, unsigned &Idx) { - // FIXME: we need unique IDs for identifiers. - std::string Str; - unsigned Length = Record[Idx++]; - Str.resize(Length); - for (unsigned I = 0; I != Length; ++I) - Str[I] = Record[Idx++]; - return &Context.Idents.get(Str); + pch::IdentID ID = Record[Idx++]; + if (ID == 0) + return 0; + + if (!IdentifierTable || IdentifierData.empty()) { + Error("No identifier table in PCH file"); + return 0; + } + + if (IdentifierData[ID - 1] & 0x01) { + uint64_t Offset = IdentifierData[ID - 1]; + IdentifierData[ID - 1] = reinterpret_cast<uint64_t>( + &Context.Idents.get(IdentifierTable + Offset)); + } + + return reinterpret_cast<const IdentifierInfo *>(IdentifierData[ID - 1]); } DeclarationName 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) { |