From 6aff871a84182a63bb4f4e7e7a3c773f257108fa Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Wed, 31 Oct 2007 22:44:07 +0000 Subject: [PATCH] Implemented more of serialization/deserialization for ASTContext. We now (hypothetically) read in/write out most of the types. Bugs likely exist. llvm-svn: 43584 --- clang/AST/ASTContext.cpp | 110 ++++++++++++++++++++++----- clang/include/clang/AST/ASTContext.h | 7 +- 2 files changed, 98 insertions(+), 19 deletions(-) diff --git a/clang/AST/ASTContext.cpp b/clang/AST/ASTContext.cpp index 816a50b29c4b..b83d33da7ccd 100644 --- a/clang/AST/ASTContext.cpp +++ b/clang/AST/ASTContext.cpp @@ -1286,14 +1286,48 @@ bool ASTContext::typesAreCompatible(QualType lhs, QualType rhs) { } -template -static inline void EmitSet(const llvm::FoldingSet& set, llvm::Serializer& S) { +template static inline +void EmitSet(const llvm::FoldingSet& set, llvm::Serializer& S) { S.EmitInt(set.size()); - llvm::FoldingSet& Set = const_cast&>(set); - for (typename llvm::FoldingSet::iterator I=Set.begin(), E=Set.end(); + for (typename llvm::FoldingSet::const_iterator I=set.begin(), E=set.end(); I!=E; ++I) - S.Emit(*I); + S.EmitOwnedPtr(&*I); +} + +template static inline +void ReadSet(llvm::FoldingSet& set, std::vector& V, + llvm::Deserializer& D) { + + unsigned size = D.ReadInt(); + + for (unsigned i = 0 ; i < size; ++i) { + T* t = D.ReadOwnedPtr(); + set.GetOrInsertNode(t); + V.push_back(t); + } +} + +template static inline +void EmitVector(const std::vector& V, llvm::Serializer& S) { + S.EmitInt(V.size()); + + for (typename std::vector::const_iterator I=V.begin(),E=V.end(); I!=E;++I) + S.EmitOwnedPtr(*I); +} + +template static inline +void ReadVector(std::vector& V, std::vector& Types, + llvm::Deserializer& D) { + + unsigned size = D.ReadInt(); + V.reserve(size); + + for (unsigned i = 0 ; i < size ; ++i) { + T* t = D.Materialize(); + V.push_back(t); + Types.push_back(t); + } } /// Emit - Serialize an ASTContext object to Bitcode. @@ -1302,25 +1336,67 @@ void ASTContext::Emit(llvm::Serializer& S) const { S.EmitRef(Target); S.EmitRef(Idents); S.EmitRef(Selectors); - // FIXME: BuildinInfo - EmitSet(ComplexTypes,S); - EmitSet(PointerTypes,S); - EmitSet(ReferenceTypes,S); - EmitSet(ConstantArrayTypes,S); - EmitSet(IncompleteVariableArrayTypes,S); + // Emit the size of the type vector so that we can reserve that size + // when we reconstitute the ASTContext object. + S.Emit(Types.size()); + + // Emit pointers to builtin types. Although these objects will be + // reconsituted automatically when ASTContext is created, any pointers to them + // will not be (and will need to be patched). Thus we must register them + // with the Serialize anyway as pointed-to-objects, even if we won't + // serialize them out using EmitOwnedPtr. - S.EmitInt(CompleteVariableArrayTypes.size()); - for (unsigned i = 0; i < CompleteVariableArrayTypes.size(); ++i) - S.Emit(*CompleteVariableArrayTypes[i]); + for (std::vector::const_iterator I=Types.begin(),E=Types.end(); + I!=E; ++I) + if (const BuiltinType* BT = dyn_cast(*I)) + S.EmitPtr(BT); + else { + // Sleazy hack: builtins are at the beginning of the vector. Stop + // processing the type-vector when we hit the first non-builtin. + break; + } + // Emit the remaining types. + EmitSet(ComplexTypes, S); + EmitSet(PointerTypes, S); + EmitSet(ReferenceTypes, S); + EmitSet(ConstantArrayTypes, S); + EmitSet(IncompleteVariableArrayTypes, S); + EmitVector(CompleteVariableArrayTypes, S); EmitSet(VectorTypes,S); EmitSet(FunctionTypeNoProtos,S); EmitSet(FunctionTypeProtos,S); + // FIXME: EmitSet(ObjcQualifiedInterfaceTypes,S); // FIXME: RecourdLayoutInfo - // FIXME: Builtins. - } - +ASTContext* ASTContext::Materialize(llvm::Deserializer& D) { + SourceManager &SM = D.ReadRef(); + TargetInfo &t = D.ReadRef(); + IdentifierTable &idents = D.ReadRef(); + SelectorTable &sels = D.ReadRef(); + + unsigned size_reserve = D.ReadInt(); + + ASTContext* A = new ASTContext(SM,t,idents,sels,size_reserve); + + // Register the addresses of the BuiltinTypes with the Deserializer. + // FIXME: How brittle is this? + for (std::vector::iterator I=A->Types.begin(),E=A->Types.end(); + I!=E; ++I) + D.RegisterPtr(cast(*I)); + + ReadSet(A->ComplexTypes, A->Types, D); + ReadSet(A->PointerTypes, A->Types, D); + ReadSet(A->ReferenceTypes, A->Types, D); + ReadSet(A->ConstantArrayTypes, A->Types, D); + ReadSet(A->IncompleteVariableArrayTypes, A->Types, D); + ReadVector(A->CompleteVariableArrayTypes, A->Types, D); + ReadSet(A->VectorTypes, A->Types, D); + ReadSet(A->FunctionTypeNoProtos, A->Types, D); + ReadSet(A->FunctionTypeProtos, A->Types, D); + + return A; +} diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 5db8a3440808..8e92c7c24587 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -87,12 +87,15 @@ public: QualType VoidPtrTy; ASTContext(SourceManager &SM, TargetInfo &t, IdentifierTable &idents, - SelectorTable &sels) : + SelectorTable &sels, unsigned size_reserve=0 ) : CFConstantStringTypeDecl(0), SourceMgr(SM), Target(t), Idents(idents), Selectors(sels) { + + if (size_reserve > 0) Types.reserve(size_reserve); InitBuiltinTypes(); BuiltinInfo.InitializeBuiltins(idents, Target); - } + } + ~ASTContext(); void PrintStats() const;