From: Argyrios Kyrtzidis Date: Sun, 24 Oct 2010 17:26:54 +0000 (+0000) Subject: Keep track in chained PCH of implicit members that were added after the definition... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b6cc0e1a789c3f33e3f4b1ee768e679a9beab941;p=clang Keep track in chained PCH of implicit members that were added after the definition was completed. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@117240 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/ASTMutationListener.h b/include/clang/AST/ASTMutationListener.h index 72e4571cc8..de8cef5f52 100644 --- a/include/clang/AST/ASTMutationListener.h +++ b/include/clang/AST/ASTMutationListener.h @@ -27,6 +27,9 @@ public: /// \brief A new TagDecl definition was completed. virtual void CompletedTagDefinition(const TagDecl *D) { } + + /// \brief An implicit member was added after the definition was completed. + virtual void AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) {} }; } // end namespace clang diff --git a/include/clang/Serialization/ASTWriter.h b/include/clang/Serialization/ASTWriter.h index 7b6b00155d..da47e159ec 100644 --- a/include/clang/Serialization/ASTWriter.h +++ b/include/clang/Serialization/ASTWriter.h @@ -514,6 +514,7 @@ public: // ASTMutationListener implementation. virtual void CompletedTagDefinition(const TagDecl *D); + virtual void AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D); }; /// \brief AST and semantic-analysis consumer that generates a diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp index f37151439f..0e70053866 100644 --- a/lib/AST/DeclCXX.cpp +++ b/lib/AST/DeclCXX.cpp @@ -364,12 +364,11 @@ void CXXRecordDecl::addedMember(Decl *D) { } if (D->isImplicit()) { - // Notify the serializer that an implicit member changed the definition. - // A chained PCH will write the whole definition again. - // FIXME: Make a notification about the specific change (through a listener - // interface) so the changes that the serializer records are more - // fine grained. - data().Definition->setChangedSinceDeserialization(true); + // Notify that an implicit member was added after the definition + // was completed. + if (!isBeingDefined()) + if (ASTMutationListener *L = getASTMutationListener()) + L->AddedCXXImplicitMember(data().Definition, D); if (CXXConstructorDecl *Constructor = dyn_cast(D)) { // If this is the implicit default constructor, note that we have now diff --git a/lib/Serialization/ASTCommon.h b/lib/Serialization/ASTCommon.h index 36958c7500..5ed607a86e 100644 --- a/lib/Serialization/ASTCommon.h +++ b/lib/Serialization/ASTCommon.h @@ -21,7 +21,8 @@ namespace clang { namespace serialization { enum DeclUpdateKind { - UPD_CXX_SET_DEFINITIONDATA + UPD_CXX_SET_DEFINITIONDATA, + UPD_CXX_ADDED_IMPLICIT_MEMBER }; TypeIdx TypeIdxFromBuiltin(const BuiltinType *BT); diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp index f4568a7e70..7192195501 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/lib/Serialization/ASTReaderDecl.cpp @@ -1599,6 +1599,10 @@ void ASTDeclReader::UpdateDecl(Decl *D, const RecordData &Record) { InitializeCXXDefinitionData(RD, DefinitionDecl, Record, Idx); break; } + + case UPD_CXX_ADDED_IMPLICIT_MEMBER: + cast(D)->addedMember(Reader.GetDecl(Record[Idx++])); + break; } } } diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index 436525f199..340f0cc559 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -3326,3 +3326,17 @@ void ASTWriter::CompletedTagDefinition(const TagDecl *D) { } } } + +void ASTWriter::AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) { + assert(D->isImplicit()); + if (!(D->getPCHLevel() == 0 && RD->getPCHLevel() > 0)) + return; // Not a source member added to a class from PCH. + if (!isa(D)) + return; // We are interested in lazily declared implicit methods. + + // A decl coming from PCH was modified. + assert(RD->isDefinition()); + UpdateRecord &Record = DeclUpdates[RD]; + Record.push_back(UPD_CXX_ADDED_IMPLICIT_MEMBER); + AddDeclRef(D, Record); +}