From 5b9dc7caaef0469babc45dd8e713727a136ce517 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Thu, 28 Jul 2011 14:54:22 +0000 Subject: [PATCH] Make Sema::ReferencedSelectors lazily deserialized. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@136357 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Sema/ExternalSemaSource.h | 12 +++++++++- include/clang/Serialization/ASTReader.h | 3 +++ lib/Sema/SemaDeclObjC.cpp | 8 +++++++ lib/Serialization/ASTReader.cpp | 31 ++++++++++++++----------- 4 files changed, 40 insertions(+), 14 deletions(-) diff --git a/include/clang/Sema/ExternalSemaSource.h b/include/clang/Sema/ExternalSemaSource.h index c9da3fefbb..d8d6abb650 100644 --- a/include/clang/Sema/ExternalSemaSource.h +++ b/include/clang/Sema/ExternalSemaSource.h @@ -125,7 +125,17 @@ public: /// to introduce the same declarations repeatedly. virtual void ReadLocallyScopedExternalDecls( SmallVectorImpl &Decls) {} - + + /// \brief Read the set of referenced selectors known to the + /// external Sema source. + /// + /// The external source should append its own referenced selectors 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 selectors repeatedly. + virtual void ReadReferencedSelectors( + SmallVectorImpl > &Sels) {} + // isa/cast/dyn_cast support static bool classof(const ExternalASTSource *Source) { return Source->SemaSource; diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h index 7de5ec1ffc..0113e6f98d 100644 --- a/include/clang/Serialization/ASTReader.h +++ b/include/clang/Serialization/ASTReader.h @@ -1391,6 +1391,9 @@ public: virtual void ReadLocallyScopedExternalDecls( SmallVectorImpl &Decls); + virtual void ReadReferencedSelectors( + SmallVectorImpl > &Sels); + /// \brief Load a selector from disk, registering its ID if it exists. void LoadSelector(Selector Sel); diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index e9a39b614e..b91a81372f 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -2765,6 +2765,14 @@ void Sema::CollectIvarsToConstructOrDestruct(ObjCInterfaceDecl *OI, } void Sema::DiagnoseUseOfUnimplementedSelectors() { + // Load referenced selectors from the external source. + if (ExternalSource) { + SmallVector, 4> Sels; + ExternalSource->ReadReferencedSelectors(Sels); + for (unsigned I = 0, N = Sels.size(); I != N; ++I) + ReferencedSelectors[Sels[I].first] = Sels[I].second; + } + // Warning will be issued only when selector table is // generated (which means there is at lease one implementation // in the TU). This is to match gcc's behavior. diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 0ae1f62aa3..a0f8f68dfd 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -4366,19 +4366,6 @@ void ASTReader::InitializeSema(Sema &S) { SemaObj->StdBadAlloc = SemaDeclRefs[1]; } - // If there are @selector references added them to its pool. This is for - // implementation of -Wselector. - if (!ReferencedSelectorsData.empty()) { - unsigned int DataSize = ReferencedSelectorsData.size()-1; - unsigned I = 0; - while (I < DataSize) { - Selector Sel = DecodeSelector(ReferencedSelectorsData[I++]); - SourceLocation SelLoc - = SourceLocation::getFromRawEncoding(ReferencedSelectorsData[I++]); - SemaObj->ReferencedSelectors.insert(std::make_pair(Sel, SelLoc)); - } - } - // The special data sets below always come from the most recent PCH, // which is at the front of the chain. Module &F = ModuleMgr.getPrimaryModule(); @@ -4617,6 +4604,24 @@ ASTReader::ReadLocallyScopedExternalDecls(SmallVectorImpl &Decls) { LocallyScopedExternalDecls.clear(); } +void ASTReader::ReadReferencedSelectors( + SmallVectorImpl > &Sels) { + if (ReferencedSelectorsData.empty()) + return; + + // If there are @selector references added them to its pool. This is for + // implementation of -Wselector. + unsigned int DataSize = ReferencedSelectorsData.size()-1; + unsigned I = 0; + while (I < DataSize) { + Selector Sel = DecodeSelector(ReferencedSelectorsData[I++]); + SourceLocation SelLoc + = SourceLocation::getFromRawEncoding(ReferencedSelectorsData[I++]); + Sels.push_back(std::make_pair(Sel, SelLoc)); + } + ReferencedSelectorsData.clear(); +} + void ASTReader::LoadSelector(Selector Sel) { // It would be complicated to avoid reading the methods anyway. So don't. ReadMethodPool(Sel);