diff options
-rw-r--r-- | Basic/IdentifierTable.cpp | 108 | ||||
-rw-r--r-- | include/clang/Basic/IdentifierTable.h | 40 |
2 files changed, 80 insertions, 68 deletions
diff --git a/Basic/IdentifierTable.cpp b/Basic/IdentifierTable.cpp index 01c2c17240..a69e65fe19 100644 --- a/Basic/IdentifierTable.cpp +++ b/Basic/IdentifierTable.cpp @@ -382,63 +382,81 @@ SelectorTable::~SelectorTable() { // Serialization for IdentifierInfo and IdentifierTable. //===----------------------------------------------------------------------===// -void llvm::SerializeTrait<IdentifierInfo>::Emit(llvm::Serializer& S, - const IdentifierInfo& I) { - - S.EmitInt(I.getTokenID()); - S.EmitInt(I.getBuiltinID()); - S.EmitInt(I.getObjCKeywordID()); - S.EmitBool(I.hasMacroDefinition()); - S.EmitBool(I.isExtensionToken()); - S.EmitBool(I.isPoisoned()); - S.EmitBool(I.isOtherTargetMacro()); - S.EmitBool(I.isCPlusPlusOperatorKeyword()); - S.EmitBool(I.isNonPortableBuiltin()); +void IdentifierInfo::Emit(llvm::Serializer& S) const { + S.EmitInt(getTokenID()); + S.EmitInt(getBuiltinID()); + S.EmitInt(getObjCKeywordID()); + S.EmitBool(hasMacroDefinition()); + S.EmitBool(isExtensionToken()); + S.EmitBool(isPoisoned()); + S.EmitBool(isOtherTargetMacro()); + S.EmitBool(isCPlusPlusOperatorKeyword()); + S.EmitBool(isNonPortableBuiltin()); + // FIXME: FETokenInfo } -void llvm::SerializeTrait<IdentifierInfo>::Read(llvm::Deserializer& D, - IdentifierInfo& I) { - I.setTokenID((tok::TokenKind) D.ReadInt()); - I.setBuiltinID(D.ReadInt()); - I.setObjCKeywordID((tok::ObjCKeywordKind) D.ReadInt()); - I.setHasMacroDefinition(D.ReadBool()); - I.setIsExtensionToken(D.ReadBool()); - I.setIsPoisoned(D.ReadBool()); - I.setIsOtherTargetMacro(D.ReadBool()); - I.setIsCPlusPlusOperatorKeyword(D.ReadBool()); - I.setNonPortableBuiltin(D.ReadBool()); +void IdentifierInfo::Read(llvm::Deserializer& D) { + setTokenID((tok::TokenKind) D.ReadInt()); + setBuiltinID(D.ReadInt()); + setObjCKeywordID((tok::ObjCKeywordKind) D.ReadInt()); + setHasMacroDefinition(D.ReadBool()); + setIsExtensionToken(D.ReadBool()); + setIsPoisoned(D.ReadBool()); + setIsOtherTargetMacro(D.ReadBool()); + setIsCPlusPlusOperatorKeyword(D.ReadBool()); + setNonPortableBuiltin(D.ReadBool()); + // FIXME: FETokenInfo } -void llvm::SerializeTrait<IdentifierTable>::Emit(llvm::Serializer& S, - const IdentifierTable& T){ - S.Emit<unsigned>(T.size()); +void IdentifierTable::Emit(llvm::Serializer& S) const { + S.EnterBlock(); - for (clang::IdentifierTable::iterator I=T.begin(), E=T.end(); I != E; ++I) { - S.EmitCStr(I->getKeyData()); - S.EmitPtr(&I->getValue()); - S.Emit(I->getValue()); + for (iterator I=begin(), E=end(); I != E; ++I) { + const char* Key = I->getKeyData(); + const IdentifierInfo* Info = &I->getValue(); + + bool KeyRegistered = true; // FIXME: S.isRegistered(Key); + bool InfoRegistered = true; // FIXME: S.isRegistered(Info); + + if (KeyRegistered || InfoRegistered) { + // These acrobatics are so that we don't incur the cost of registering + // a pointer with the backpatcher during deserialization if nobody + // references the object. + S.EmitPtr(InfoRegistered ? Info : NULL); + S.EmitPtr(KeyRegistered ? Key : NULL); + S.EmitCStr(Key); + S.Emit(*Info); + } } + + S.ExitBlock(); } -void llvm::SerializeTrait<IdentifierTable>::Read(llvm::Deserializer& D, - IdentifierTable& T) { - unsigned len = D.ReadInt(); +IdentifierTable* IdentifierTable::Materialize(llvm::Deserializer& D) { + llvm::Deserializer::Location BLoc = D.GetCurrentBlockLocation(); + std::vector<char> buff; buff.reserve(200); + + IdentifierTable* t = new IdentifierTable(); - for (unsigned i = 0; i < len; ++i) { + while (!D.FinishedBlock(BLoc)) { + llvm::SerializedPtrID InfoPtrID = D.ReadPtrID(); + llvm::SerializedPtrID KeyPtrID = D.ReadPtrID(); + D.ReadCStr(buff); - IdentifierInfo& Info = T.get(&buff[0],&buff[0]+buff.size()); - D.RegisterPtr(&Info); - D.Read(Info); + + llvm::StringMapEntry<IdentifierInfo>& Entry = + t->HashTable.GetOrCreateValue(&buff[0],&buff[0]+buff.size()); + + D.Read(Entry.getValue()); + + if (InfoPtrID) + D.RegisterRef(InfoPtrID,Entry.getValue()); + + if (KeyPtrID) + D.RegisterPtr(KeyPtrID,Entry.getKeyData()); } -} - -IdentifierTable* -llvm::SerializeTrait<IdentifierTable>::Materialize(llvm::Deserializer& D) -{ - IdentifierTable* t = new IdentifierTable(); - D.Read(*t); + return t; } - diff --git a/include/clang/Basic/IdentifierTable.h b/include/clang/Basic/IdentifierTable.h index b505176c04..ca3f147062 100644 --- a/include/clang/Basic/IdentifierTable.h +++ b/include/clang/Basic/IdentifierTable.h @@ -18,7 +18,7 @@ #include "clang/Basic/TokenKinds.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/SmallString.h" -#include "llvm/Bitcode/Serialization.h" +#include "llvm/Bitcode/SerializationFwd.h" #include <string> #include <cassert> @@ -137,6 +137,12 @@ public: template<typename T> T *getFETokenInfo() const { return static_cast<T*>(FETokenInfo); } void setFETokenInfo(void *T) { FETokenInfo = T; } + + /// Emit - Serialize this IdentifierInfo to a bitstream. + void Emit(llvm::Serializer& S) const; + + /// Read - Deserialize an IdentifierInfo object from a bitstream. + void Read(llvm::Deserializer& D); }; /// IdentifierTable - This table implements an efficient mapping from strings to @@ -182,12 +188,19 @@ public: void AddKeywords(const LangOptions &LangOpts); + /// Emit - Serialize this IdentifierTable to a bitstream. This should + /// be called AFTER objects that externally reference the identifiers in the + /// table have been serialized. This is because only the identifiers that + /// are actually referenced are serialized. + void Emit(llvm::Serializer& S) const; + + /// Materialize - Deserialize an IdentifierTable from a bitstream. + static IdentifierTable* Materialize(llvm::Deserializer& D); + private: /// This ctor is not intended to be used by anyone except for object /// serialization. - IdentifierTable(); - - friend struct llvm::SerializeTrait<IdentifierTable>; + IdentifierTable(); }; /// Selector - This smart pointer class efficiently represents Objective-C @@ -304,25 +317,6 @@ struct DenseMapInfo<clang::Selector> { static bool isPod() { return true; } }; - -/// Define SerializeTrait to enable serialization for IdentifierInfos. -template <> -struct SerializeTrait<clang::IdentifierInfo> { - static void Emit(Serializer& S, const clang::IdentifierInfo& I); - static void Read(Deserializer& S, clang::IdentifierInfo& I); -}; - -/// Define SerializeTrait to enable serialization for IdentifierTables. -template <> -struct SerializeTrait<clang::IdentifierTable> { - static void Emit(Serializer& S, const clang::IdentifierTable& X); - static void Read(Deserializer& S, clang::IdentifierTable& X); - -private: - static clang::IdentifierTable* Materialize(Deserializer& D); - friend class Deserializer; -}; - } // end namespace llvm #endif |