[cfe-commits] r43266 - in /cfe/trunk: Basic/IdentifierTable.cpp Basic/TokenKinds.cpp Driver/Makefile Driver/SerializationTest.cpp include/clang/Basic/IdentifierTable.h include/clang/Basic/TokenKinds.h

Ted Kremenek kremenek at apple.com
Tue Oct 23 15:18:38 PDT 2007


Author: kremenek
Date: Tue Oct 23 17:18:37 2007
New Revision: 43266

URL: http://llvm.org/viewvc/llvm-project?rev=43266&view=rev
Log:
Implemented serialization for IdentifierInfo and IdentifierTable.
Updated serialization test code in the driver to test serialization of
these types.

Modified:
    cfe/trunk/Basic/IdentifierTable.cpp
    cfe/trunk/Basic/TokenKinds.cpp
    cfe/trunk/Driver/Makefile
    cfe/trunk/Driver/SerializationTest.cpp
    cfe/trunk/include/clang/Basic/IdentifierTable.h
    cfe/trunk/include/clang/Basic/TokenKinds.h

Modified: cfe/trunk/Basic/IdentifierTable.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Basic/IdentifierTable.cpp?rev=43266&r1=43265&r2=43266&view=diff

==============================================================================
--- cfe/trunk/Basic/IdentifierTable.cpp (original)
+++ cfe/trunk/Basic/IdentifierTable.cpp Tue Oct 23 17:18:37 2007
@@ -16,6 +16,8 @@
 #include "clang/Basic/LangOptions.h"
 #include "llvm/ADT/FoldingSet.h"
 #include "llvm/ADT/DenseMap.h"
+#include "llvm/Bitcode/Serialization.h"
+
 using namespace clang;
 
 //===----------------------------------------------------------------------===//
@@ -48,6 +50,9 @@
   AddKeywords(LangOpts);
 }
 
+// This cstor is intended to be used only for serialization.
+IdentifierTable::IdentifierTable() : HashTable(8192) {}
+
 //===----------------------------------------------------------------------===//
 // Language Keyword Implementation
 //===----------------------------------------------------------------------===//
@@ -93,7 +98,7 @@
                                   IdentifierTable &Table) {
   IdentifierInfo &Info = Table.get(Keyword, Keyword + KWLen);
   Info.setTokenID(TokenCode);
-  Info.setIsCPlusplusOperatorKeyword();
+  Info.setIsCPlusPlusOperatorKeyword();
 }
 
 /// AddObjCKeyword - Register an Objective-C @keyword like "class" "selector" or 
@@ -372,4 +377,63 @@
   delete static_cast<llvm::FoldingSet<MultiKeywordSelector> *>(Impl);
 }
 
+//===----------------------------------------------------------------------===//
+// Serialization for IdentifierInfo and IdentifierTable.
+//===----------------------------------------------------------------------===//
+
+void llvm::SerializeTrait<IdentifierInfo>::Serialize(llvm::Serializer& S,
+                                                    const IdentifierInfo& I) {
+
+  S.Emit<tok::TokenKind>(I.getTokenID());
+  S.EmitInt(I.getBuiltinID(),9);
+  S.Emit<tok::ObjCKeywordKind>(I.getObjCKeywordID());  
+  S.Emit(I.hasMacroDefinition());
+  S.Emit(I.isExtensionToken());
+  S.Emit(I.isPoisoned());
+  S.Emit(I.isOtherTargetMacro());
+  S.Emit(I.isCPlusPlusOperatorKeyword());
+  S.Emit(I.isNonPortableBuiltin());   
+}
+
+void llvm::SerializeTrait<IdentifierInfo>::Deserialize(llvm::Deserializer& D,
+                                                       IdentifierInfo& I) {
+  tok::TokenKind X;
+  I.setTokenID(D.Read<tok::TokenKind>(X));
+
+  I.setBuiltinID(D.ReadInt(9));  
+  
+  tok::ObjCKeywordKind Y;
+  I.setObjCKeywordID(D.Read<tok::ObjCKeywordKind>(Y));
+  
+  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 llvm::SerializeTrait<IdentifierTable>::Serialize(llvm::Serializer& S,
+                                                      const IdentifierTable& T){
+  S.Emit<unsigned>(T.size());
+  
+  for (clang::IdentifierTable::iterator I=T.begin(), E=T.end(); I != E; ++I) {
+    S.EmitCString(I->getKeyData());
+    S.Emit(I->getValue());
+  }
+}
+
+void llvm::SerializeTrait<IdentifierTable>::Deserialize(llvm::Deserializer& D,
+                                                        IdentifierTable& T) {
+  unsigned len = D.ReadInt();
+  std::vector<char> buff;
+  buff.reserve(200);
+  
+  for (unsigned i = 0; i < len; ++i) {
+    D.ReadCString(buff);
+    IdentifierInfo& Info = T.get(&buff[0],&buff[0]+buff.size());
+    D.Read(Info);
+  }
+}
+  
 

Modified: cfe/trunk/Basic/TokenKinds.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Basic/TokenKinds.cpp?rev=43266&r1=43265&r2=43266&view=diff

==============================================================================
--- cfe/trunk/Basic/TokenKinds.cpp (original)
+++ cfe/trunk/Basic/TokenKinds.cpp Tue Oct 23 17:18:37 2007
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Basic/TokenKinds.h"
+#include "llvm/Bitcode/Serialization.h"
 #include <cassert>
 using namespace clang;
 
@@ -26,3 +27,37 @@
   assert(Kind < tok::NUM_TOKENS);
   return TokNames[Kind];
 }
+
+// Serialization traits for TokenKind, PPKeywordKind, and ObjCKeywordKind
+
+void llvm::SerializeTrait<tok::TokenKind>::Serialize(llvm::Serializer& S,
+                                                     tok::TokenKind X) {
+  S.EmitEnum(X,0,tok::NUM_TOKENS-1);
+}
+
+void llvm::SerializeTrait<tok::TokenKind>::Deserialize(llvm::Deserializer& D,
+                                                       tok::TokenKind& X) {
+  X = D.ReadEnum<tok::TokenKind>(0,tok::NUM_TOKENS-1);
+}
+
+void llvm::SerializeTrait<tok::PPKeywordKind>::Serialize(llvm::Serializer& S,
+                                                       tok::PPKeywordKind X) {
+  S.EmitEnum(X,0,tok::NUM_PP_KEYWORDS-1);
+}
+
+void llvm::SerializeTrait<tok::PPKeywordKind>::Deserialize(llvm::Deserializer& D,
+                                                      tok::PPKeywordKind& X) {
+  X = D.ReadEnum<tok::PPKeywordKind>(0,tok::NUM_PP_KEYWORDS-1);
+}
+
+void
+llvm::SerializeTrait<tok::ObjCKeywordKind>::Serialize(llvm::Serializer& S,
+                                                      tok::ObjCKeywordKind X) {
+  S.EmitEnum(X,0,tok::NUM_OBJC_KEYWORDS-1);
+}
+
+void
+llvm::SerializeTrait<tok::ObjCKeywordKind>::Deserialize(llvm::Deserializer& D,
+                                                     tok::ObjCKeywordKind& X) {
+  X = D.ReadEnum<tok::ObjCKeywordKind>(0,tok::NUM_OBJC_KEYWORDS-1);
+}
\ No newline at end of file

Modified: cfe/trunk/Driver/Makefile
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/Makefile?rev=43266&r1=43265&r2=43266&view=diff

==============================================================================
--- cfe/trunk/Driver/Makefile (original)
+++ cfe/trunk/Driver/Makefile Tue Oct 23 17:18:37 2007
@@ -5,6 +5,7 @@
 TOOLNAME = clang
 USEDLIBS = clangCodeGen.a clangAnalysis.a clangRewrite.a clangSEMA.a \
            clangAST.a clangParse.a clangLex.a clangBasic.a \
-           LLVMCore.a LLVMSupport.a LLVMSystem.a
+           LLVMCore.a LLVMSupport.a LLVMSystem.a \
+           LLVMBitWriter.a LLVMBitReader.a
 
 include $(LEVEL)/Makefile.common

Modified: cfe/trunk/Driver/SerializationTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/SerializationTest.cpp?rev=43266&r1=43265&r2=43266&view=diff

==============================================================================
--- cfe/trunk/Driver/SerializationTest.cpp (original)
+++ cfe/trunk/Driver/SerializationTest.cpp Tue Oct 23 17:18:37 2007
@@ -19,226 +19,148 @@
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
 #include "llvm/System/Path.h"
-#include "llvm/Bitcode/BitstreamWriter.h"
-#include <fstream>
-#include <iostream>
+#include "llvm/Support/Streams.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Bitcode/Serialization.h"
+#include <stdio.h>
+
+//===----------------------------------------------------------------------===//
+// Driver code.
+//===----------------------------------------------------------------------===//
 
 using namespace clang;
-using llvm::BitstreamWriter;
-using std::cerr;
-using std::cout;
-using std::endl;
-using std::flush;
-
-namespace llvm {  
-template<typename T> struct IntrospectionTrait {
-  struct Flags { 
-    enum { isPod = false, UniqueInstances = false, UniqueRefs = false };
-  };
-  
-  template<typename Introspector>
-  struct Ops {
-    static inline void Introspect(T& X, Introspector& I) {
-      assert (false && "Introspect not implemented.");
-    }
-  };
-};
-}
 
 namespace {
-class SerializationTest : public ASTConsumer {
-  IdentifierTable* IdTable;
-  unsigned MainFileID;
-public:
-  void Initialize(ASTContext& Context, unsigned mainFileID) {
-    IdTable = &Context.Idents;
-    MainFileID = mainFileID;
-    RunSerializationTest();
-  }
-  
-  void RunSerializationTest();
-  bool WriteAll(llvm::sys::Path& Filename);
-  
-  virtual void HandleTopLevelDecl(Decl *D) {}
-};
+  template<typename T>
+  struct Janitor {
+    T* Obj;
+    Janitor(T* obj) : Obj(obj) {}
+    ~Janitor() { delete Obj; }
+  };
+} // end anonymous namespace
 
-class Writer {
-  std::vector<unsigned char> Buffer;
-  BitstreamWriter Stream;
-  std::ostream& Out;
-public:
-  
-  enum { IdentifierTableBID = 0x8 };
-  
-  Writer(std::ostream& out) : Stream(Buffer), Out(out) {
-    Buffer.reserve(256*1024);
+namespace {
+  class SerializationTest : public ASTConsumer {
+    IdentifierTable* IdTable;
+    unsigned MainFileID;
+  public:
+    void Initialize(ASTContext& Context, unsigned mainFileID) {
+      IdTable = &Context.Idents;
+      MainFileID = mainFileID;
+    }
     
-    // Emit the file header.
-    Stream.Emit((unsigned)'B', 8);
-    Stream.Emit((unsigned)'C', 8);
-    Stream.Emit(0xC, 4);
-    Stream.Emit(0xF, 4);
-    Stream.Emit(0xE, 4);
-    Stream.Emit(0x0, 4);
-  }
-  
-  ~Writer() {
-    Out.write((char*)&Buffer.front(), Buffer.size());
-    Out.flush();
-  }
-  
-  template <typename T> inline void operator()(T& x) {
-    llvm::IntrospectionTrait<T>::template Ops<Writer>::Introspect(x,*this);
-  }
+    ~SerializationTest() {
+      RunSerializationTest();
+    }
     
-  template <typename T> inline void operator()(T& x, unsigned bits) {
-    llvm::IntrospectionTrait<T>::template Ops<Writer>::Introspect(x,bits,*this);
-  }
-  
-  template <typename T> inline void operator()(const T& x) {
-    operator()(const_cast<T&>(x));
-  }
-  
-  template <typename T> inline void operator()(const T& x, unsigned bits) {
-    operator()(const_cast<T&>(x),bits);
-  }  
-  
-  inline void operator()(bool X) { Stream.Emit(X,1); }
-  inline void operator()(unsigned X) { Stream.Emit(X,32); }
-  inline void operator()(unsigned X, unsigned bits, bool VBR=false) {
-    if (VBR) Stream.Emit(X,bits);
-    else Stream.Emit(X,bits);
-  }
-  
-  inline BitstreamWriter& getStream() {
-    return Stream;
-  }
-  
-  template <typename T> inline void EnterSubblock(unsigned CodeLen) {
-    Stream.EnterSubblock(8,CodeLen);
-  }
-  
-  inline void ExitBlock() { Stream.ExitBlock(); }
-  
-};  
-  
-} // end anonymous namespace  
-
-//===----------------------------------------------------------------------===//
-// External Interface.
-//===----------------------------------------------------------------------===//
+    void RunSerializationTest();
+    bool WriteTable(llvm::sys::Path& Filename, IdentifierTable* T);
+    IdentifierTable* ReadTable(llvm::sys::Path& Filename);
+    
+    virtual void HandleTopLevelDecl(Decl *D) {}
+  };
+} // end anonymous namespace
 
 ASTConsumer* clang::CreateSerializationTest() {
   return new SerializationTest();
 }
-  
-//===----------------------------------------------------------------------===//
-// Serialization "Driver" code.
-//===----------------------------------------------------------------------===//
 
 void SerializationTest::RunSerializationTest() { 
   std::string ErrMsg;
   llvm::sys::Path Filename = llvm::sys::Path::GetTemporaryDirectory(&ErrMsg);
-
+  
   if (Filename.isEmpty()) {
-    cerr << "Error: " << ErrMsg << "\n";
+    llvm::cerr << "Error: " << ErrMsg << "\n";
     return;
   }
   
-  Filename.appendComponent("test.cfe_bc");
+  Filename.appendComponent("test.ast");
   
   if (Filename.makeUnique(true,&ErrMsg)) {
-    cerr << "Error: " << ErrMsg << "\n";
+    llvm::cerr << "Error: " << ErrMsg << "\n";
     return;
   }
   
-  if (!WriteAll(Filename))
-    return;
-  
-  cout << "Wrote file: " << Filename.c_str() << "\n";
+  llvm::cerr << "Writing out Identifier table\n";
+  WriteTable(Filename,IdTable);
+  llvm::cerr << "Reading in Identifier Table\n";
+  IdentifierTable* T = ReadTable(Filename);
+  Janitor<IdentifierTable> roger(T);
+  
+  Filename.appendSuffix("2");
+  llvm::cerr << "Writing out Identifier table (2)\n";
+  WriteTable(Filename,T);
+  llvm::cerr << "Reading in Identifier Table (2)\n";
+  Janitor<IdentifierTable> wilco(ReadTable(Filename));
 }
 
-bool SerializationTest::WriteAll(llvm::sys::Path& Filename) {  
-  std::ofstream Out(Filename.c_str());
+bool SerializationTest::WriteTable(llvm::sys::Path& Filename,
+                                   IdentifierTable* T) {
+  if (!T)
+    return false;
+  
+  std::vector<unsigned char> Buffer;
+  Buffer.reserve(256*1024);
   
-  if (!Out) {
-    cerr << "Error: Cannot open " << Filename.c_str() << "\n";
+  llvm::BitstreamWriter Stream(Buffer);
+  
+  Stream.Emit((unsigned)'B', 8);
+  Stream.Emit((unsigned)'C', 8);
+  Stream.Emit(0xC, 4);
+  Stream.Emit(0xF, 4);
+  Stream.Emit(0xE, 4);
+  Stream.Emit(0x0, 4);
+
+  llvm::Serializer S(Stream);
+  S.Emit(*T);
+  S.Flush();
+  
+  if (FILE *fp = fopen(Filename.c_str(),"wb")) {
+    fwrite((char*)&Buffer.front(), sizeof(char), Buffer.size(), fp);
+    fclose(fp);
+  }
+  else { 
+    llvm::cerr << "Error: Cannot open " << Filename.c_str() << "\n";
     return false;
   }
-    
-  Writer W(Out);
-  W(*IdTable);
-
-  W.getStream().FlushToWord();
+  
+  llvm::cerr << "Wrote file: " << Filename.c_str() << "\n";
   return true;
 }
 
-//===----------------------------------------------------------------------===//
-// Serialization Methods.
-//===----------------------------------------------------------------------===//
-
-namespace llvm {
 
-struct IntrospectionPrimitivesFlags {
-  enum { isPod = true, UniqueInstances = false, UniqueRefs = false };
-};
+IdentifierTable* SerializationTest::ReadTable(llvm::sys::Path& Filename) {
+  llvm::MemoryBuffer* Buffer = 
+    llvm::MemoryBuffer::getFile(Filename.c_str(), strlen(Filename.c_str()));
   
-
-template<> struct
-IntrospectionTrait<bool>::Flags : public IntrospectionPrimitivesFlags {};
+  if(!Buffer) {
+    llvm::cerr << "Error reading file\n";
+    return NULL;
+  }
   
-template<> struct
-IntrospectionTrait<unsigned>::Flags : public IntrospectionPrimitivesFlags {};
-
-template<> struct
-IntrospectionTrait<short>::Flags : public IntrospectionPrimitivesFlags {};
-
-
-
-template<> 
-struct IntrospectionTrait<clang::IdentifierInfo> {
-
-  struct Flags { 
-    enum { isPod = false,  // Cannot copy via memcpy.  Must use copy-ctor.    
-           hasUniqueInstances = true, // Two pointers with different
-                                      // addreses point to objects
-                                      // that are not equal to each other.    
-           hasUniqueReferences = true // Two (non-temporary) pointers                                    
-                                      // will point to distinct instances.
-    };
-  };
-
-  template<typename Introspector>
-  struct Ops {
-    static void Introspect(clang::IdentifierInfo& X, Introspector& I) {
-  //    I(X.getTokenID());
-      I(X.getBuiltinID(),9); // FIXME: do 9 bit specialization.
-  //    I(X.getObjCKeywordID());
-      I(X.hasMacroDefinition());
-      I(X.isExtensionToken());
-      I(X.isPoisoned());
-      I(X.isOtherTargetMacro());
-      I(X.isCPlusPlusOperatorKeyword());
-      I(X.isNonPortableBuiltin());
-    }
-  };
-};
+  Janitor<llvm::MemoryBuffer> AutoReleaseBuffer(Buffer);
   
-template<> template<>
-struct IntrospectionTrait<clang::IdentifierTable>::Ops<Writer> {
-  static void Introspect(clang::IdentifierTable& X, Writer& W) {
-    W.EnterSubblock<clang::IdentifierTable>(1);
-/*        
-    for (clang::IdentifierTable::iterator I = X.begin(), E = X.end();
-         I != E; ++I)
-      W(I->getValue());
-   */ 
-    W.ExitBlock();
+  if (Buffer->getBufferSize() & 0x3) {
+    llvm::cerr << "AST file should be a multiple of 4 bytes in length\n";
+    return NULL;
   }
-};
-
   
-
+  unsigned char *BufPtr = (unsigned char *)Buffer->getBufferStart();
+  llvm::BitstreamReader Stream(BufPtr,BufPtr+Buffer->getBufferSize());
+  
+  // Sniff for the signature.
+  if (Stream.Read(8) != 'B' ||
+      Stream.Read(8) != 'C' ||
+      Stream.Read(4) != 0xC ||
+      Stream.Read(4) != 0xF ||
+      Stream.Read(4) != 0xE ||
+      Stream.Read(4) != 0x0) {
+    llvm::cerr << "Invalid AST-bitcode signature\n";
+    return NULL;
+  }
   
-} // end namespace llvm
+  llvm::Deserializer D(Stream);
 
+  llvm::cerr << "Materializing identifier table.\n";
+  return D.Materialize<IdentifierTable>();
+}

Modified: cfe/trunk/include/clang/Basic/IdentifierTable.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/IdentifierTable.h?rev=43266&r1=43265&r2=43266&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/IdentifierTable.h (original)
+++ cfe/trunk/include/clang/Basic/IdentifierTable.h Tue Oct 23 17:18:37 2007
@@ -23,8 +23,10 @@
 
 
 namespace llvm {
-  template <typename T> struct IntrospectionTrait;
   template <typename T> struct DenseMapInfo;
+  template <typename T> struct SerializeTrait;
+  class Serializer;
+  class Deserializer;
 }
 
 namespace clang {
@@ -129,7 +131,7 @@
 
   /// isCPlusPlusOperatorKeyword/setIsCPlusPlusOperatorKeyword controls whether
   /// this identifier is a C++ alternate representation of an operator.
-  void setIsCPlusplusOperatorKeyword(bool Val = true)
+  void setIsCPlusPlusOperatorKeyword(bool Val = true)
     { IsCPPOperatorKeyword = Val; }
   bool isCPlusPlusOperatorKeyword() const { return IsCPPOperatorKeyword; }
 
@@ -138,13 +140,6 @@
   template<typename T>
   T *getFETokenInfo() const { return static_cast<T*>(FETokenInfo); }
   void setFETokenInfo(void *T) { FETokenInfo = T; }
-  
-  // For serialization and profiling.
-#if defined(_MSC_VER) && _MSC_VER <= 1400   // workaround for VC++ upto V8.0
-  template<typename T> friend class /*llvm::*/IntrospectionTrait;
-#else
-  template<typename T> friend class llvm::IntrospectionTrait;
-#endif
 };
 
 /// IdentifierTable - This table implements an efficient mapping from strings to
@@ -182,18 +177,20 @@
   iterator begin() const { return HashTable.begin(); }
   iterator end() const   { return HashTable.end(); }
   
+  unsigned size() const { return HashTable.size(); }
+  
   /// PrintStats - Print some statistics to stderr that indicate how well the
   /// hashing is doing.
   void PrintStats() const;
   
-  // For serialization and profiling.
-#if defined(_MSC_VER) && _MSC_VER <= 1400   // workaround for VC++ upto V8.0
-  template<typename T> friend class /*llvm::*/IntrospectionTrait;
-#else
-  template<typename T> friend class llvm::IntrospectionTrait;
-#endif
-private:
   void AddKeywords(const LangOptions &LangOpts);
+
+private:  
+  /// This ctor is not intended to be used by anyone except for object
+  /// serialization.
+  IdentifierTable();
+  
+  friend class llvm::SerializeTrait<IdentifierTable>;
 };
 
 /// Selector - This smart pointer class efficiently represents Objective-C
@@ -311,6 +308,27 @@
   static bool isPod() { return true; }
 };
 
+/// Define SerializeTrait to enable serialization for IdentifierInfos.
+template <>
+struct SerializeTrait<clang::IdentifierInfo> {
+  static void Serialize(llvm::Serializer& S, const clang::IdentifierInfo& I);
+  static void Deserialize(llvm::Deserializer& S, clang::IdentifierInfo& I);
+};
+
+/// Define SerializeTrait to enable serialization for IdentifierTables.  
+template <>
+struct SerializeTrait<clang::IdentifierTable> {
+  static void Serialize(llvm::Serializer& S, const clang::IdentifierTable& X);
+  static void Deserialize(llvm::Deserializer& S, clang::IdentifierTable& X);
+
+private:
+  static inline clang::IdentifierTable* Instantiate() { 
+    return new clang::IdentifierTable();
+  }
+  
+  friend class Deserializer;
+};
+
 }  // end namespace llvm
 
 #endif

Modified: cfe/trunk/include/clang/Basic/TokenKinds.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TokenKinds.h?rev=43266&r1=43265&r2=43266&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/TokenKinds.h (original)
+++ cfe/trunk/include/clang/Basic/TokenKinds.h Tue Oct 23 17:18:37 2007
@@ -48,4 +48,33 @@
 }  // end namespace tok
 }  // end namespace clang
 
+//===----------------------------------------------------------------------===//
+// Serialization traits.
+//===----------------------------------------------------------------------===//
+
+namespace llvm {
+  template <typename T> struct SerializeTrait;
+  class Serializer;
+  class Deserializer;
+  
+template<>
+struct SerializeTrait<clang::tok::TokenKind> {
+  static void Serialize(llvm::Serializer& S, clang::tok::TokenKind X);
+  static void Deserialize(llvm::Deserializer& D, clang::tok::TokenKind& X);
+};
+  
+template<>
+struct SerializeTrait<clang::tok::PPKeywordKind> {
+  static void Serialize(llvm::Serializer& S, clang::tok::PPKeywordKind X);
+  static void Deserialize(llvm::Deserializer& D, clang::tok::PPKeywordKind& X);
+};
+
+template<>
+struct SerializeTrait<clang::tok::ObjCKeywordKind> {
+  static void Serialize(llvm::Serializer& S, clang::tok::ObjCKeywordKind X);
+  static void Deserialize(llvm::Deserializer& D, clang::tok::ObjCKeywordKind& X);
+};
+  
+} // end namespace llvm
+
 #endif





More information about the cfe-commits mailing list