diff --git a/clang/AST/TypeSerialization.cpp b/clang/AST/TypeSerialization.cpp new file mode 100644 index 000000000000..3e6ad49bec47 --- /dev/null +++ b/clang/AST/TypeSerialization.cpp @@ -0,0 +1,127 @@ +//===--- TypeSerialization.cpp - Serialization of Decls ---------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Ted Kremenek and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This files defines methods that implement bitcode serialization for Types. +// +//===----------------------------------------------------------------------===// + +#include "clang/AST/Type.h" +#include "llvm/Bitcode/Serialize.h" +#include "llvm/Bitcode/Deserialize.h" + +using namespace clang; + +void QualType::Emit(llvm::Serializer& S) const { + S.EmitPtr(getAsOpaquePtr()); + S.EmitInt(getQualifiers()); +} + +void QualType::Read(llvm::Deserializer& D) { + D.ReadPtr(ThePtr); + ThePtr |= D.ReadInt(); +} + +/* FIXME: Either remove this method or complete it. + +void Type::Emit(llvm::Serializer& S) { + switch (getTypeClass()) { + default: + assert (false && "Serialization for type class not implemented."); + break; + + case Type::Builtin: + cast(this)->Emit(S); + break; + } +} + */ + +void Type::EmitTypeInternal(llvm::Serializer& S) const { + S.Emit(CanonicalType); +} + +void Type::ReadTypeInternal(llvm::Deserializer& D) { + D.Read(CanonicalType); +} + +void ComplexType::Emit(llvm::Serializer& S) const { + EmitTypeInternal(S); + S.Emit(ElementType); +} + +ComplexType* ComplexType::Materialize(llvm::Deserializer& D) { + ComplexType* T = new ComplexType(QualType(),QualType()); + T->ReadTypeInternal(D); + D.Read(T->ElementType); + return T; +} + +void PointerType::Emit(llvm::Serializer& S) const { + EmitTypeInternal(S); + S.Emit(PointeeType); +} + +PointerType* PointerType::Materialize(llvm::Deserializer& D) { + PointerType* T = new PointerType(QualType(),QualType()); + T->ReadTypeInternal(D); + D.Read(T->PointeeType); + return T; +} + +void ReferenceType::Emit(llvm::Serializer& S) const { + EmitTypeInternal(S); + S.Emit(ReferenceeType); +} + +ReferenceType* ReferenceType::Materialize(llvm::Deserializer& D) { + ReferenceType* T = new ReferenceType(QualType(),QualType()); + T->ReadTypeInternal(D); + D.Read(T->ReferenceeType); + return T; +} + +void ArrayType::EmitArrayTypeInternal(llvm::Serializer& S) const { + EmitTypeInternal(S); + S.Emit(ElementType); + S.EmitInt(SizeModifier); + S.EmitInt(IndexTypeQuals); +} + +void ArrayType::ReadArrayTypeInternal(llvm::Deserializer& D) { + ReadTypeInternal(D); + D.Read(ElementType); + SizeModifier = static_cast(D.ReadInt()); + IndexTypeQuals = D.ReadInt(); +} + +void ConstantArrayType::Emit(llvm::Serializer& S) const { +#if 0 + // FIXME: APInt serialization + S.Emit(Size); +#endif + EmitArrayTypeInternal(S); +} + +ConstantArrayType* ConstantArrayType::Materialize(llvm::Deserializer& D) { +#if 0 + llvm::APInt x = S.ReadVal(D); + + // "Default" construct the array. + ConstantArrayType* T = + new ConstantArrayType(QualType(), QualType(), x, ArrayType::Normal, 0); + + // Deserialize the internal values. + T->ReadArrayTypeInternal(D); + + return T; +#else + return NULL; +#endif + +} diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 8e57185f702e..35eca6a43544 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -17,6 +17,7 @@ #include "llvm/Support/Casting.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/APSInt.h" +#include "llvm/Bitcode/SerializationFwd.h" using llvm::isa; using llvm::cast; @@ -153,6 +154,17 @@ public: /// appropriate type qualifiers on it. inline QualType getCanonicalType() const; + /// Emit - Serialize a QualType using a Bitcode Serializer. + void Emit(llvm::Serializer& S) const; + + /// Read - Deserialize a QualType using a Bitcode Deserializer. This + /// deserialization requires that a QualType be default constructed + /// first. This is because internally the deserialization relies on + /// pointer backpatching performed by the Deserializer. Deserialization + /// of a QualType should only be done on an instance of QualType that + /// exists, in place, within its containing object. + void Read(llvm::Deserializer& D); + private: }; @@ -169,7 +181,8 @@ template<> struct simplify_type { }; template<> struct simplify_type< ::clang::QualType> : public simplify_type {}; -} + +} // end namespace llvm namespace clang { @@ -223,6 +236,10 @@ protected: : CanonicalType(Canonical.isNull() ? QualType(this_(),0) : Canonical), TC(tc){} virtual ~Type(); friend class ASTContext; + + void EmitTypeInternal(llvm::Serializer& S) const; + void ReadTypeInternal(llvm::Deserializer& D); + public: TypeClass getTypeClass() const { return static_cast(TC); } @@ -359,6 +376,8 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == Builtin; } static bool classof(const BuiltinType *) { return true; } + + void Emit(llvm::Serializer& S) const; }; /// ComplexType - C99 6.2.5p11 - Complex values. This supports the C99 complex @@ -385,6 +404,9 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == Complex; } static bool classof(const ComplexType *) { return true; } + + void Emit(llvm::Serializer& S) const; + static ComplexType* Materialize(llvm::Deserializer& D); }; @@ -412,6 +434,9 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == Pointer; } static bool classof(const PointerType *) { return true; } + + void Emit(llvm::Serializer& S) const; + static PointerType* Materialize(llvm::Deserializer& D); }; /// ReferenceType - C++ 8.3.2 - Reference Declarators. @@ -436,6 +461,9 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == Reference; } static bool classof(const ReferenceType *) { return true; } + + void Emit(llvm::Serializer& S) const; + static ReferenceType* Materialize(llvm::Deserializer& D); }; /// ArrayType - C99 6.7.5.2 - Array Declarators. @@ -482,6 +510,10 @@ public: T->getTypeClass() == VariableArray; } static bool classof(const ArrayType *) { return true; } + +protected: + void EmitArrayTypeInternal(llvm::Serializer& S) const; + void ReadArrayTypeInternal(llvm::Deserializer& S); }; class ConstantArrayType : public ArrayType, public llvm::FoldingSetNode { @@ -519,6 +551,9 @@ public: return T->getTypeClass() == ConstantArray; } static bool classof(const ConstantArrayType *) { return true; } + + void Emit(llvm::Serializer& S) const; + static ConstantArrayType* Materialize(llvm::Deserializer& D); }; // FIXME: VariableArrayType's aren't uniqued (since expressions aren't).