From aad48b6b2dfc81ad36a05d161c775cd6aab5b339 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Wed, 14 Nov 2007 08:06:37 +0000 Subject: [PATCH] Implemented serialization of RecordDecls. Changed serialization of TagType to have an owning pointer to the referred TagDecl. This should hopefully fix a bug where TagDecls (including decls from structs, etc.) were not serialized. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@44106 91177308-0d34-0410-b5e6-96231b3b80d8 --- AST/DeclSerialization.cpp | 43 +++++++++++++++++++++++++++++++++++++++ AST/TypeSerialization.cpp | 24 ++++++++++++++++------ include/clang/AST/Decl.h | 9 ++++++++ include/clang/AST/Type.h | 9 ++++---- 4 files changed, 75 insertions(+), 10 deletions(-) diff --git a/AST/DeclSerialization.cpp b/AST/DeclSerialization.cpp index b881cbe5b5..cfab8cc76d 100644 --- a/AST/DeclSerialization.cpp +++ b/AST/DeclSerialization.cpp @@ -52,6 +52,9 @@ Decl* Decl::Create(Deserializer& D) { case Function: return FunctionDecl::CreateImpl(D); + case Struct: + return RecordDecl::CreateImpl(k,D); + case Typedef: return TypedefDecl::CreateImpl(D); } @@ -267,6 +270,46 @@ FunctionDecl* FunctionDecl::CreateImpl(Deserializer& D) { return decl; } +//===----------------------------------------------------------------------===// +// RecordDecl Serialization. +//===----------------------------------------------------------------------===// + +void RecordDecl::EmitImpl(llvm::Serializer& S) const { + ScopedDecl::EmitInRec(S); + S.EmitBool(hasFlexibleArrayMember()); + S.EmitSInt(getNumMembers()); + if (getNumMembers() > 0) { + assert (Members); + S.BatchEmitOwnedPtrs((unsigned) getNumMembers(), + (Decl**) &Members[0],getNextDeclarator()); + } + else + ScopedDecl::EmitOutRec(S); +} + +RecordDecl* RecordDecl::CreateImpl(Decl::Kind DK, Deserializer& D) { + RecordDecl* decl = new RecordDecl(DK,SourceLocation(),NULL,NULL); + + decl->ScopedDecl::ReadInRec(D); + decl->setHasFlexibleArrayMember(D.ReadBool()); + decl->NumMembers = D.ReadSInt(); + + if (decl->getNumMembers() > 0) { + Decl* next_declarator; + decl->Members = new FieldDecl*[(unsigned) decl->getNumMembers()]; + + D.BatchReadOwnedPtrs((unsigned) decl->getNumMembers(), + (Decl**) &decl->Members[0], + next_declarator); + + decl->setNextDeclarator(cast_or_null(next_declarator)); + } + else + decl->ScopedDecl::ReadOutRec(D); + + return decl; +} + //===----------------------------------------------------------------------===// // TypedefDecl Serialization. //===----------------------------------------------------------------------===// diff --git a/AST/TypeSerialization.cpp b/AST/TypeSerialization.cpp index ba32abfb5d..68471ad197 100644 --- a/AST/TypeSerialization.cpp +++ b/AST/TypeSerialization.cpp @@ -86,7 +86,7 @@ void Type::Create(ASTContext& Context, unsigned i, Deserializer& D) { break; case Type::Tagged: - D.RegisterPtr(PtrID,TagType::CreateImpl(Context,D)); + TagType::CreateImpl(Context,PtrID,D); break; case Type::TypeName: @@ -189,12 +189,24 @@ Type* PointerType::CreateImpl(ASTContext& Context, Deserializer& D) { //===----------------------------------------------------------------------===// void TagType::EmitImpl(Serializer& S) const { - S.EmitPtr(Decl); + S.EmitOwnedPtr(getDecl()); } -Type* TagType::CreateImpl(ASTContext& Context, Deserializer& D) { - TagType* T = cast(Context.getTagDeclType(NULL).getTypePtr()); - D.ReadPtr(T->Decl); // May be backpatched. +Type* TagType::CreateImpl(ASTContext& Context, SerializedPtrID& PtrID, + Deserializer& D) { + + std::vector& Types = + const_cast&>(Context.getTypes()); + + TagType* T = new TagType(NULL,QualType()); + Types.push_back(T); + + // Forward register the type pointer before deserializing the decl. + D.RegisterPtr(PtrID,T); + + // Deserialize the decl. + T->decl = cast(D.ReadOwnedPtr()); + return T; } @@ -215,7 +227,7 @@ Type* TypedefType::CreateImpl(ASTContext& Context, Deserializer& D) { Types.push_back(T); D.ReadPtr(T->Decl); // May be backpatched. - + assert(false); return T; } diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 04e919caad..0ffb3277dd 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -701,6 +701,15 @@ public: return D->getKind() >= RecordFirst && D->getKind() <= RecordLast; } static bool classof(const RecordDecl *D) { return true; } + +protected: + /// EmitImpl - Serialize this TypedefDecl. Called by Decl::Emit. + virtual void EmitImpl(llvm::Serializer& S) const; + + /// CreateImpl - Deserialize a TypedefDecl. Called by Decl::Create. + static RecordDecl* CreateImpl(Kind DK, llvm::Deserializer& D); + + friend Decl* Decl::Create(llvm::Deserializer& D); }; } // end namespace clang diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index fb3e38f123..c42a1b00c9 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -874,12 +874,12 @@ public: }; class TagType : public Type { - TagDecl *Decl; - TagType(TagDecl *D, QualType can) : Type(Tagged, can), Decl(D) {} + TagDecl *decl; + TagType(TagDecl *D, QualType can) : Type(Tagged, can), decl(D) {} friend class ASTContext; // ASTContext creates these. public: - TagDecl *getDecl() const { return Decl; } + TagDecl *getDecl() const { return decl; } virtual void getAsStringInternal(std::string &InnerString) const; @@ -888,7 +888,8 @@ public: protected: virtual void EmitImpl(llvm::Serializer& S) const; - static Type* CreateImpl(ASTContext& Context, llvm::Deserializer& D); + static Type* CreateImpl(ASTContext& Context, llvm::SerializedPtrID& PtrID, + llvm::Deserializer& D); friend class Type; }; -- 2.40.0