From: Ted Kremenek Date: Fri, 30 Nov 2007 22:46:56 +0000 (+0000) Subject: Implemented serialization of SelectorTable and Selectors. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bdbb285aed1bb1e20090a16929f4c1da33d2d5c5;p=clang Implemented serialization of SelectorTable and Selectors. Modified serialization of IdentifierTable to self-register itself with the Deserializer. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@44471 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/Basic/IdentifierTable.cpp b/Basic/IdentifierTable.cpp index 73be7d34dd..5459d609c3 100644 --- a/Basic/IdentifierTable.cpp +++ b/Basic/IdentifierTable.cpp @@ -258,6 +258,8 @@ unsigned llvm::DenseMapInfo::getHashValue(clang::Selector S) { /// this class is provided strictly through Selector. namespace clang { class MultiKeywordSelector : public llvm::FoldingSetNode { + friend SelectorTable* SelectorTable::CreateAndRegister(llvm::Deserializer&); + MultiKeywordSelector(unsigned nKeys) : NumArgs(nKeys) {} public: unsigned NumArgs; @@ -265,11 +267,13 @@ public: MultiKeywordSelector(unsigned nKeys, IdentifierInfo **IIV) { assert((nKeys > 1) && "not a multi-keyword selector"); NumArgs = nKeys; + // Fill in the trailing keyword array. IdentifierInfo **KeyInfo = reinterpret_cast(this+1); for (unsigned i = 0; i != nKeys; ++i) KeyInfo[i] = IIV[i]; - } + } + // getName - Derive the full selector name and return it. std::string getName() const; @@ -422,6 +426,8 @@ void IdentifierInfo::Read(llvm::Deserializer& D) { void IdentifierTable::Emit(llvm::Serializer& S) const { S.EnterBlock(); + S.EmitPtr(this); + for (iterator I=begin(), E=end(); I != E; ++I) { const char* Key = I->getKeyData(); const IdentifierInfo* Info = &I->getValue(); @@ -443,13 +449,14 @@ void IdentifierTable::Emit(llvm::Serializer& S) const { S.ExitBlock(); } -IdentifierTable* IdentifierTable::Create(llvm::Deserializer& D) { +IdentifierTable* IdentifierTable::CreateAndRegister(llvm::Deserializer& D) { llvm::Deserializer::Location BLoc = D.getCurrentBlockLocation(); std::vector buff; buff.reserve(200); IdentifierTable* t = new IdentifierTable(); + D.RegisterPtr(t); while (!D.FinishedBlock(BLoc)) { llvm::SerializedPtrID InfoPtrID = D.ReadPtrID(); @@ -471,3 +478,71 @@ IdentifierTable* IdentifierTable::Create(llvm::Deserializer& D) { return t; } + +//===----------------------------------------------------------------------===// +// Serialization for Selector and SelectorTable. +//===----------------------------------------------------------------------===// + +void Selector::Emit(llvm::Serializer& S) const { + S.EmitInt(getIdentifierInfoFlag()); + S.EmitPtr(reinterpret_cast(InfoPtr & ~ArgFlags)); +} + +Selector Selector::ReadVal(llvm::Deserializer& D) { + unsigned flag = D.ReadInt(); + + uintptr_t ptr; + D.ReadUIntPtr(ptr,false); // No backpatching. + + return Selector(ptr | flag); +} + +void SelectorTable::Emit(llvm::Serializer& S) const { + typedef llvm::FoldingSet::iterator iterator; + llvm::FoldingSet *SelTab; + SelTab = static_cast *>(Impl); + + S.EnterBlock(); + + S.EmitPtr(this); + + for (iterator I=SelTab->begin(), E=SelTab->end(); I != E; ++I) { + S.FlushRecord(); // Start a new record. + S.EmitInt(I->getNumArgs()); + + for (MultiKeywordSelector::keyword_iterator KI = I->keyword_begin(), + KE = I->keyword_end(); KI != KE; ++KI) + S.EmitPtr(*KI); + } + + S.ExitBlock(); +} + +SelectorTable* SelectorTable::CreateAndRegister(llvm::Deserializer& D) { + llvm::Deserializer::Location BLoc = D.getCurrentBlockLocation(); + + SelectorTable* t = new SelectorTable(); + D.RegisterPtr(t); + + llvm::FoldingSet& SelTab = + *static_cast*>(t->Impl); + + while (!D.FinishedBlock(BLoc)) { + unsigned nKeys = D.ReadInt(); + + MultiKeywordSelector *SI = + (MultiKeywordSelector*)malloc(sizeof(MultiKeywordSelector) + + nKeys*sizeof(IdentifierInfo *)); + + new (SI) MultiKeywordSelector(nKeys); + + IdentifierInfo **KeyInfo = reinterpret_cast(SI+1); + + for (unsigned i = 0; i != nKeys; ++i) + D.ReadPtr(KeyInfo[i],false); + + SelTab.GetOrInsertNode(SI); + } + + return t; +} diff --git a/Driver/SerializationTest.cpp b/Driver/SerializationTest.cpp index 9beb92e130..f8d4b7820e 100644 --- a/Driver/SerializationTest.cpp +++ b/Driver/SerializationTest.cpp @@ -53,9 +53,9 @@ class SerializationTest : public ASTConsumer { ASTContext* Context; std::list Decls; - enum { BasicMetadataBlock, - ASTContextBlock, - DeclsBlock }; + enum { BasicMetadataBlock = 1, + ASTContextBlock = 2, + DeclsBlock = 3 }; public: SerializationTest() : Context(NULL) {}; @@ -163,6 +163,10 @@ void SerializationTest::Serialize(llvm::sys::Path& Filename, Sezr.EnterBlock(BasicMetadataBlock); + // Block for SourceManager and Target. Allows easy skipping around + // to the Selectors during deserialization. + Sezr.EnterBlock(); + // "Fake" emit the SourceManager. llvm::cerr << "Faux-serializing: SourceManager.\n"; Sezr.EmitPtr(&Context->SourceMgr); @@ -171,13 +175,15 @@ void SerializationTest::Serialize(llvm::sys::Path& Filename, llvm::cerr << "Faux-serializing: Target.\n"; Sezr.EmitPtr(&Context->Target); - // "Fake" emit Selectors. - llvm::cerr << "Faux-serializing: Selectors.\n"; - Sezr.EmitPtr(&Context->Selectors); + Sezr.ExitBlock(); + + // Emit the Selectors. + llvm::cerr << "Serializing: Selectors.\n"; + Sezr.Emit(Context->Selectors); // Emit the Identifier Table. llvm::cerr << "Serializing: IdentifierTable.\n"; - Sezr.EmitOwnedPtr(&Context->Idents); + Sezr.Emit(Context->Idents); Sezr.ExitBlock(); @@ -254,19 +260,23 @@ void SerializationTest::Deserialize(llvm::sys::Path& Filename, llvm::cerr << "Faux-Deserializing: Target.\n"; Dezr.RegisterPtr(&Context->Target); - // "Fake" read the Selectors. - llvm::cerr << "Faux-Deserializing: Selectors.\n"; - Dezr.RegisterPtr(&Context->Selectors); + // For Selectors, we must read the identifier table first because the + // SelectorTable depends on the identifiers being already deserialized. + llvm::Deserializer::Location SelectorBlockLoc = Dezr.getCurrentBlockLocation(); + Dezr.SkipBlock(); // Read the identifier table. llvm::cerr << "Deserializing: IdentifierTable\n"; - Dezr.ReadOwnedPtr(); + IdentifierTable::CreateAndRegister(Dezr); - // Now jump back to ASTContextBlock and read the ASTContext. - Dezr.JumpTo(ASTContextBlockLoc); + // Now jump back and read the selectors. + llvm::cerr << "Deserializing: Selectors\n"; + Dezr.JumpTo(SelectorBlockLoc); + SelectorTable::CreateAndRegister(Dezr); - // Read the ASTContext. + // Now jump back to ASTContextBlock and read the ASTContext. llvm::cerr << "Deserializing: ASTContext.\n"; + Dezr.JumpTo(ASTContextBlockLoc); Dezr.ReadOwnedPtr(); // "Rewind" the stream. Find the block with the serialized top-level decls. diff --git a/include/clang/Basic/IdentifierTable.h b/include/clang/Basic/IdentifierTable.h index 79d8573221..f783c50c2a 100644 --- a/include/clang/Basic/IdentifierTable.h +++ b/include/clang/Basic/IdentifierTable.h @@ -195,7 +195,7 @@ public: void Emit(llvm::Serializer& S) const; /// Create - Deserialize an IdentifierTable from a bitstream. - static IdentifierTable* Create(llvm::Deserializer& D); + static IdentifierTable* CreateAndRegister(llvm::Deserializer& D); private: /// This ctor is not intended to be used by anyone except for object @@ -227,7 +227,7 @@ class Selector { InfoPtr = reinterpret_cast(SI); assert((InfoPtr & ArgFlags) == 0 &&"Insufficiently aligned IdentifierInfo"); } - Selector(intptr_t V) : InfoPtr(V) {} + Selector(uintptr_t V) : InfoPtr(V) {} public: friend class SelectorTable; // only the SelectorTable can create these. @@ -269,6 +269,12 @@ public: static Selector getTombstoneMarker() { return Selector(uintptr_t(-2)); } + + // Emit - Emit a selector to bitcode. + void Emit(llvm::Serializer& S) const; + + // ReadVal - Read a selector from bitcode. + static Selector ReadVal(llvm::Deserializer& D); }; /// SelectorTable - This table allows us to fully hide how we implement @@ -292,6 +298,12 @@ public: Selector getNullarySelector(IdentifierInfo *ID) { return Selector(ID, 0); } + + // Emit - Emit a SelectorTable to bitcode. + void Emit(llvm::Serializer& S) const; + + // Create - Reconstitute a SelectorTable from bitcode. + static SelectorTable* CreateAndRegister(llvm::Deserializer& D); }; } // end namespace clang