// 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;
}
-
#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>
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
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
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