From a126f17ca83b985300c1f65cee647bea108db657 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Thu, 28 Jul 2011 00:53:40 +0000 Subject: [PATCH] Switch Sema::DynamicClasses over to LazyVector git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@136317 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Sema/ExternalSemaSource.h | 9 +++++++++ include/clang/Sema/Sema.h | 6 +++++- include/clang/Serialization/ASTReader.h | 2 ++ lib/Sema/Sema.cpp | 11 ++++++----- lib/Serialization/ASTReader.cpp | 13 ++++++++++--- lib/Serialization/ASTWriter.cpp | 7 ++----- 6 files changed, 34 insertions(+), 14 deletions(-) diff --git a/include/clang/Sema/ExternalSemaSource.h b/include/clang/Sema/ExternalSemaSource.h index 939c9dfabe..a4c869b07e 100644 --- a/include/clang/Sema/ExternalSemaSource.h +++ b/include/clang/Sema/ExternalSemaSource.h @@ -19,6 +19,7 @@ namespace clang { class CXXConstructorDecl; +class CXXRecordDecl; class DeclaratorDecl; class LookupResult; struct ObjCMethodList; @@ -107,6 +108,14 @@ public: /// introduce the same declarations repeatedly. virtual void ReadExtVectorDecls(SmallVectorImpl &Decls) {} + /// \brief Read the set of dynamic classes known to the external Sema source. + /// + /// The external source should append its own dynamic classes to + /// the given vector of declarations. Note that this routine may be + /// invoked multiple times; the external source should take care not to + /// introduce the same declarations repeatedly. + virtual void ReadDynamicClasses(SmallVectorImpl &Decls) {} + // isa/cast/dyn_cast support static bool classof(const ExternalASTSource *Source) { return Source->SemaSource; diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 520fe8fc94..f38fdff9ed 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -3375,9 +3375,13 @@ public: /// by code generation). llvm::DenseMap VTablesUsed; + typedef LazyVector + DynamicClassesType; + /// \brief A list of all of the dynamic classes in this translation /// unit. - SmallVector DynamicClasses; + DynamicClassesType DynamicClasses; /// \brief Note that the vtable for the given class was used at the /// given location. diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h index ec8ed5f5cb..5169cf44a6 100644 --- a/include/clang/Serialization/ASTReader.h +++ b/include/clang/Serialization/ASTReader.h @@ -1382,6 +1382,8 @@ public: virtual void ReadExtVectorDecls(SmallVectorImpl &Decls); + virtual void ReadDynamicClasses(SmallVectorImpl &Decls); + /// \brief Load a selector from disk, registering its ID if it exists. void LoadSelector(Selector Sel); diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index b2f90613eb..e598956eeb 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -408,14 +408,15 @@ void Sema::ActOnEndOfTranslationUnit() { // If any dynamic classes have their key function defined within // this translation unit, then those vtables are considered "used" and must // be emitted. - for (unsigned I = 0, N = DynamicClasses.size(); I != N; ++I) { - assert(!DynamicClasses[I]->isDependentType() && + for (DynamicClassesType::iterator I = DynamicClasses.begin(ExternalSource), + E = DynamicClasses.end(); + I != E; ++I) { + assert(!(*I)->isDependentType() && "Should not see dependent types here!"); - if (const CXXMethodDecl *KeyFunction - = Context.getKeyFunction(DynamicClasses[I])) { + if (const CXXMethodDecl *KeyFunction = Context.getKeyFunction(*I)) { const FunctionDecl *Definition = 0; if (KeyFunction->hasBody(Definition)) - MarkVTableUsed(Definition->getLocation(), DynamicClasses[I], true); + MarkVTableUsed(Definition->getLocation(), *I, true); } } diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index e8ae251e5a..8b2d1a270e 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -4341,9 +4341,6 @@ void ASTReader::InitializeSema(Sema &S) { // If there were any dynamic classes declarations, deserialize them // and add them to Sema's vector of such declarations. - for (unsigned I = 0, N = DynamicClasses.size(); I != N; ++I) - SemaObj->DynamicClasses.push_back( - cast(GetDecl(DynamicClasses[I]))); // Load the offsets of the declarations that Sema references. // They will be lazily deserialized when needed. @@ -4586,6 +4583,16 @@ void ASTReader::ReadExtVectorDecls(SmallVectorImpl &Decls) { ExtVectorDecls.clear(); } +void ASTReader::ReadDynamicClasses(SmallVectorImpl &Decls) { + for (unsigned I = 0, N = DynamicClasses.size(); I != N; ++I) { + CXXRecordDecl *D + = dyn_cast_or_null(GetDecl(DynamicClasses[I])); + if (D) + Decls.push_back(D); + } + DynamicClasses.clear(); +} + void ASTReader::LoadSelector(Selector Sel) { // It would be complicated to avoid reading the methods anyway. So don't. ReadMethodPool(Sel); diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index 3cc2dae4fc..d4692b3ed0 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -2867,8 +2867,7 @@ void ASTWriter::WriteASTCore(Sema &SemaRef, MemorizeStatCalls *StatCalls, // Build a record containing all of dynamic classes declarations. RecordData DynamicClasses; - for (unsigned I = 0, N = SemaRef.DynamicClasses.size(); I != N; ++I) - AddDeclRef(SemaRef.DynamicClasses[I], DynamicClasses); + AddLazyVectorDecls(*this, SemaRef.DynamicClasses, DynamicClasses); // Build a record containing all of pending implicit instantiations. RecordData PendingInstantiations; @@ -3137,9 +3136,7 @@ void ASTWriter::WriteASTChain(Sema &SemaRef, MemorizeStatCalls *StatCalls, // Build a record containing all of dynamic classes declarations. RecordData DynamicClasses; - for (unsigned I = 0, N = SemaRef.DynamicClasses.size(); I != N; ++I) - if (SemaRef.DynamicClasses[I]->getPCHLevel() == 0) - AddDeclRef(SemaRef.DynamicClasses[I], DynamicClasses); + AddLazyVectorDecls(*this, SemaRef.DynamicClasses, DynamicClasses); // Build a record containing all of pending implicit instantiations. RecordData PendingInstantiations; -- 2.40.0