From: Richard Smith Date: Thu, 20 Mar 2014 21:02:00 +0000 (+0000) Subject: Refactor and simplify DeclUpdates serialization. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=22b3c93d7329876ba3615ad84241bf3e9bc962aa;p=clang Refactor and simplify DeclUpdates serialization. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@204397 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Serialization/ASTWriter.h b/include/clang/Serialization/ASTWriter.h index e22d0499ec..6875c7672a 100644 --- a/include/clang/Serialization/ASTWriter.h +++ b/include/clang/Serialization/ASTWriter.h @@ -283,7 +283,33 @@ private: llvm::DenseMap MacroDefinitions; - typedef SmallVector UpdateRecord; + /// An update to a Decl. + class DeclUpdate { + /// A DeclUpdateKind. + unsigned Kind; + union { + const Decl *Dcl; + void *Type; + unsigned Loc; + }; + + public: + DeclUpdate(unsigned Kind) : Kind(Kind), Dcl(0) {} + DeclUpdate(unsigned Kind, const Decl *Dcl) : Kind(Kind), Dcl(Dcl) {} + DeclUpdate(unsigned Kind, QualType Type) + : Kind(Kind), Type(Type.getAsOpaquePtr()) {} + DeclUpdate(unsigned Kind, SourceLocation Loc) + : Kind(Kind), Loc(Loc.getRawEncoding()) {} + + unsigned getKind() const { return Kind; } + const Decl *getDecl() const { return Dcl; } + QualType getType() const { return QualType::getFromOpaquePtr(Type); } + SourceLocation getLoc() const { + return SourceLocation::getFromRawEncoding(Loc); + } + }; + + typedef SmallVector UpdateRecord; typedef llvm::DenseMap DeclUpdateMap; /// \brief Mapping from declarations that came from a chained PCH to the /// record containing modifications to them. @@ -447,7 +473,6 @@ private: void WriteIdentifierTable(Preprocessor &PP, IdentifierResolver &IdResolver, bool IsModule); void WriteAttributes(ArrayRef Attrs, RecordDataImpl &Record); - void ResolveDeclUpdatesBlocks(); void WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord); void WriteDeclReplacementsBlock(); void WriteDeclContextVisibleUpdate(const DeclContext *DC); diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index 77228229b4..a587df4145 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -4073,12 +4073,11 @@ void ASTWriter::WriteASTCore(Sema &SemaRef, // If the translation unit has an anonymous namespace, and we don't already // have an update block for it, write it as an update block. + // FIXME: Why do we not do this if there's already an update block? if (NamespaceDecl *NS = TU->getAnonymousNamespace()) { ASTWriter::UpdateRecord &Record = DeclUpdates[TU]; - if (Record.empty()) { - Record.push_back(UPD_CXX_ADDED_ANONYMOUS_NAMESPACE); - Record.push_back(reinterpret_cast(NS)); - } + if (Record.empty()) + Record.push_back({UPD_CXX_ADDED_ANONYMOUS_NAMESPACE, NS}); } // Make sure visible decls, added to DeclContexts previously loaded from @@ -4160,10 +4159,6 @@ void ASTWriter::WriteASTCore(Sema &SemaRef, Buffer.data(), Buffer.size()); } - // Resolve any declaration pointers within the declaration updates block. - // FIXME: Fold this into WriteDeclUpdatesBlocks. - ResolveDeclUpdatesBlocks(); - RecordData DeclUpdatesOffsetsRecord; // Keep writing types, declarations, and declaration update records @@ -4315,64 +4310,50 @@ void ASTWriter::WriteASTCore(Sema &SemaRef, Stream.ExitBlock(); } -/// \brief Go through the declaration update blocks and resolve declaration -/// pointers into declaration IDs. -void ASTWriter::ResolveDeclUpdatesBlocks() { - for (DeclUpdateMap::iterator - I = DeclUpdates.begin(), E = DeclUpdates.end(); I != E; ++I) { - const Decl *D = I->first; - UpdateRecord &URec = I->second; - +void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) { + if (DeclUpdates.empty()) + return; + + DeclUpdateMap LocalUpdates; + LocalUpdates.swap(DeclUpdates); + + for (auto &DeclUpdate : LocalUpdates) { + const Decl *D = DeclUpdate.first; if (isRewritten(D)) - continue; // The decl will be written completely + continue; // The decl will be written completely,no need to store updates. + + OffsetsRecord.push_back(GetDeclRef(D)); + OffsetsRecord.push_back(Stream.GetCurrentBitNo()); - unsigned Idx = 0, N = URec.size(); - while (Idx < N) { - switch ((DeclUpdateKind)URec[Idx++]) { + RecordData Record; + for (auto &Update : DeclUpdate.second) { + DeclUpdateKind Kind = (DeclUpdateKind)Update.getKind(); + + Record.push_back(Kind); + switch (Kind) { case UPD_CXX_ADDED_IMPLICIT_MEMBER: case UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION: case UPD_CXX_ADDED_ANONYMOUS_NAMESPACE: - URec[Idx] = GetDeclRef(reinterpret_cast(URec[Idx])); - ++Idx; + Record.push_back(GetDeclRef(Update.getDecl())); break; case UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER: - case UPD_DECL_MARKED_USED: - ++Idx; + AddSourceLocation(Update.getLoc(), Record); break; case UPD_CXX_DEDUCED_RETURN_TYPE: - URec[Idx] = GetOrCreateTypeID( - QualType::getFromOpaquePtr(reinterpret_cast(URec[Idx]))); - ++Idx; + Record.push_back(GetOrCreateTypeID(Update.getType())); + break; + + case UPD_DECL_MARKED_USED: break; } } - } -} -void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) { - if (DeclUpdates.empty()) - return; - - DeclUpdateMap LocalUpdates; - LocalUpdates.swap(DeclUpdates); - - for (auto &Update : LocalUpdates) { - const Decl *D = Update.first; - UpdateRecord &URec = Update.second; - - if (isRewritten(D)) - continue; // The decl will be written completely,no need to store updates. - - uint64_t Offset = Stream.GetCurrentBitNo(); - Stream.EmitRecord(DECL_UPDATES, URec); + Stream.EmitRecord(DECL_UPDATES, Record); // Flush any statements that were written as part of this update record. FlushStmts(); - - OffsetsRecord.push_back(GetDeclRef(D)); - OffsetsRecord.push_back(Offset); } } @@ -5288,9 +5269,7 @@ void ASTWriter::AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) { // A decl coming from PCH was modified. assert(RD->isCompleteDefinition()); - UpdateRecord &Record = DeclUpdates[RD]; - Record.push_back(UPD_CXX_ADDED_IMPLICIT_MEMBER); - Record.push_back(reinterpret_cast(D)); + DeclUpdates[RD].push_back({UPD_CXX_ADDED_IMPLICIT_MEMBER, D}); } void ASTWriter::AddedCXXTemplateSpecialization(const ClassTemplateDecl *TD, @@ -5301,9 +5280,7 @@ void ASTWriter::AddedCXXTemplateSpecialization(const ClassTemplateDecl *TD, if (!(!D->isFromASTFile() && TD->isFromASTFile())) return; // Not a source specialization added to a template from PCH. - UpdateRecord &Record = DeclUpdates[TD]; - Record.push_back(UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION); - Record.push_back(reinterpret_cast(D)); + DeclUpdates[TD].push_back({UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION, D}); } void ASTWriter::AddedCXXTemplateSpecialization( @@ -5314,9 +5291,7 @@ void ASTWriter::AddedCXXTemplateSpecialization( if (!(!D->isFromASTFile() && TD->isFromASTFile())) return; // Not a source specialization added to a template from PCH. - UpdateRecord &Record = DeclUpdates[TD]; - Record.push_back(UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION); - Record.push_back(reinterpret_cast(D)); + DeclUpdates[TD].push_back({UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION, D}); } void ASTWriter::AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD, @@ -5327,9 +5302,7 @@ void ASTWriter::AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD, if (!(!D->isFromASTFile() && TD->isFromASTFile())) return; // Not a source specialization added to a template from PCH. - UpdateRecord &Record = DeclUpdates[TD]; - Record.push_back(UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION); - Record.push_back(reinterpret_cast(D)); + DeclUpdates[TD].push_back({UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION, D}); } void ASTWriter::DeducedReturnType(const FunctionDecl *FD, QualType ReturnType) { @@ -5338,9 +5311,7 @@ void ASTWriter::DeducedReturnType(const FunctionDecl *FD, QualType ReturnType) { if (!FD->isFromASTFile()) return; // Not a function declared in PCH and defined outside. - UpdateRecord &Record = DeclUpdates[FD]; - Record.push_back(UPD_CXX_DEDUCED_RETURN_TYPE); - Record.push_back(reinterpret_cast(ReturnType.getAsOpaquePtr())); + DeclUpdates[FD].push_back({UPD_CXX_DEDUCED_RETURN_TYPE, ReturnType}); } void ASTWriter::CompletedImplicitDefinition(const FunctionDecl *D) { @@ -5360,10 +5331,9 @@ void ASTWriter::StaticDataMemberInstantiated(const VarDecl *D) { // Since the actual instantiation is delayed, this really means that we need // to update the instantiation location. - UpdateRecord &Record = DeclUpdates[D]; - Record.push_back(UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER); - AddSourceLocation( - D->getMemberSpecializationInfo()->getPointOfInstantiation(), Record); + DeclUpdates[D].push_back( + {UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER, + D->getMemberSpecializationInfo()->getPointOfInstantiation()}); } void ASTWriter::AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD, @@ -5397,6 +5367,5 @@ void ASTWriter::DeclarationMarkedUsed(const Decl *D) { if (!D->isFromASTFile()) return; - UpdateRecord &Record = DeclUpdates[D]; - Record.push_back(UPD_DECL_MARKED_USED); + DeclUpdates[D].push_back({UPD_DECL_MARKED_USED}); } diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp index e5e0731d1f..b8599dcaeb 100644 --- a/lib/Serialization/ASTWriterDecl.cpp +++ b/lib/Serialization/ASTWriterDecl.cpp @@ -895,9 +895,8 @@ void ASTDeclWriter::VisitNamespaceDecl(NamespaceDecl *D) { Decl *Parent = cast( D->getParent()->getRedeclContext()->getPrimaryContext()); if (Parent->isFromASTFile() || isa(Parent)) { - ASTWriter::UpdateRecord &Record = Writer.DeclUpdates[Parent]; - Record.push_back(UPD_CXX_ADDED_ANONYMOUS_NAMESPACE); - Writer.AddDeclRef(D, Record); + Writer.DeclUpdates[Parent].push_back( + {UPD_CXX_ADDED_ANONYMOUS_NAMESPACE, D}); } } }