diff options
-rw-r--r-- | include/clang/AST/ExternalASTSource.h | 16 | ||||
-rw-r--r-- | include/clang/Sema/ExternalSemaSource.h | 18 | ||||
-rw-r--r-- | include/clang/Sema/Sema.h | 6 | ||||
-rw-r--r-- | include/clang/Serialization/ASTReader.h | 3 | ||||
-rw-r--r-- | lib/Sema/Sema.cpp | 10 | ||||
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 18 | ||||
-rw-r--r-- | lib/Serialization/ASTWriter.cpp | 33 |
7 files changed, 72 insertions, 32 deletions
diff --git a/include/clang/AST/ExternalASTSource.h b/include/clang/AST/ExternalASTSource.h index 4d45a349cf..6225057659 100644 --- a/include/clang/AST/ExternalASTSource.h +++ b/include/clang/AST/ExternalASTSource.h @@ -332,6 +332,8 @@ public: /// gives us a reasonably efficient, source-order walk. int Position; + friend class LazyVector; + public: typedef T value_type; typedef value_type& reference; @@ -454,6 +456,20 @@ public: void push_back(const T& LocalValue) { Local.push_back(LocalValue); } + + void erase(iterator From, iterator To) { + if (From.Position < 0 && To.Position < 0) { + Loaded.erase(Loaded.end() + From.Position, Loaded.end() + To.Position); + return; + } + + if (From.Position < 0) { + Loaded.erase(Loaded.end() + From.Position, Loaded.end()); + From = begin(0, true); + } + + Local.erase(Local.begin() + From.Position, Local.begin() + To.Position); + } }; /// \brief A lazy pointer to a statement. diff --git a/include/clang/Sema/ExternalSemaSource.h b/include/clang/Sema/ExternalSemaSource.h index 1bc479cf4d..e0c7b4f0f0 100644 --- a/include/clang/Sema/ExternalSemaSource.h +++ b/include/clang/Sema/ExternalSemaSource.h @@ -18,10 +18,11 @@ namespace clang { +class DeclaratorDecl; +class LookupResult; struct ObjCMethodList; -class Sema; class Scope; -class LookupResult; +class Sema; class VarDecl; /// \brief An abstract interface that should be implemented by @@ -65,7 +66,7 @@ public: /// \return true to tell Sema to recover using the LookupResult. virtual bool LookupUnqualified(LookupResult &R, Scope *S) { return false; } - /// \brief Read the set of tentative definitions know to the external Sema + /// \brief Read the set of tentative definitions known to the external Sema /// source. /// /// The external source should append its own tentative definitions to the @@ -75,6 +76,17 @@ public: virtual void ReadTentativeDefinitions( SmallVectorImpl<VarDecl *> &TentativeDefs) {} + /// \brief Read the set of unused file-scope declarations known to the + /// external Sema source. + /// + /// The external source should append its own unused, filed-scope 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 ReadUnusedFileScopedDecls( + SmallVectorImpl<const DeclaratorDecl *> &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 a6fc9184bd..a14fba5300 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -288,9 +288,13 @@ public: /// \brief All the tentative definitions encountered in the TU. TentativeDefinitionsType TentativeDefinitions; + typedef LazyVector<const DeclaratorDecl *, ExternalSemaSource, + &ExternalSemaSource::ReadUnusedFileScopedDecls, 2, 2> + UnusedFileScopedDeclsType; + /// \brief The set of file scoped decls seen so far that have not been used /// and must warn if not used. Only contains the first declaration. - SmallVector<const DeclaratorDecl*, 4> UnusedFileScopedDecls; + UnusedFileScopedDeclsType UnusedFileScopedDecls; /// \brief All the delegating constructors seen so far in the file, used for /// cycle detection at the end of the TU. diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h index a8e24381e2..6fcba84171 100644 --- a/include/clang/Serialization/ASTReader.h +++ b/include/clang/Serialization/ASTReader.h @@ -1374,6 +1374,9 @@ public: virtual void ReadTentativeDefinitions( SmallVectorImpl<VarDecl *> &TentativeDefs); + virtual void ReadUnusedFileScopedDecls( + SmallVectorImpl<const DeclaratorDecl *> &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 cb240cc031..b2f90613eb 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -438,7 +438,8 @@ void Sema::ActOnEndOfTranslationUnit() { } // Remove file scoped decls that turned out to be used. - UnusedFileScopedDecls.erase(std::remove_if(UnusedFileScopedDecls.begin(), + UnusedFileScopedDecls.erase(std::remove_if(UnusedFileScopedDecls.begin(0, + true), UnusedFileScopedDecls.end(), std::bind1st(std::ptr_fun(ShouldRemoveFromUnused), this)), @@ -521,9 +522,12 @@ void Sema::ActOnEndOfTranslationUnit() { // noise. if (!Diags.hasErrorOccurred()) { // Output warning for unused file scoped decls. - for (SmallVectorImpl<const DeclaratorDecl*>::iterator - I = UnusedFileScopedDecls.begin(), + for (UnusedFileScopedDeclsType::iterator + I = UnusedFileScopedDecls.begin(ExternalSource), E = UnusedFileScopedDecls.end(); I != E; ++I) { + if (ShouldRemoveFromUnused(this, *I)) + continue; + if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(*I)) { const FunctionDecl *DiagD; if (!FD->hasBody(DiagD)) diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 9f8514f187..ba50454070 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -4328,13 +4328,6 @@ void ASTReader::InitializeSema(Sema &S) { } PreloadedDecls.clear(); - // If there were any unused file scoped decls, deserialize them and add to - // Sema's list of unused file scoped decls. - for (unsigned I = 0, N = UnusedFileScopedDecls.size(); I != N; ++I) { - DeclaratorDecl *D = cast<DeclaratorDecl>(GetDecl(UnusedFileScopedDecls[I])); - SemaObj->UnusedFileScopedDecls.push_back(D); - } - // If there were any delegating constructors, add them to Sema's list for (unsigned I = 0, N = DelegatingCtorDecls.size(); I != N; ++I) { CXXConstructorDecl *D @@ -4574,6 +4567,17 @@ void ASTReader::ReadTentativeDefinitions( TentativeDefinitions.clear(); } +void ASTReader::ReadUnusedFileScopedDecls( + SmallVectorImpl<const DeclaratorDecl *> &Decls) { + for (unsigned I = 0, N = UnusedFileScopedDecls.size(); I != N; ++I) { + DeclaratorDecl *D + = dyn_cast_or_null<DeclaratorDecl>(GetDecl(UnusedFileScopedDecls[I])); + if (D) + Decls.push_back(D); + } + UnusedFileScopedDecls.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 1acc140acd..d604da9c88 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -2777,6 +2777,15 @@ void ASTWriter::WriteAST(Sema &SemaRef, MemorizeStatCalls *StatCalls, WriteASTCore(SemaRef, StatCalls, isysroot, OutputFile); } +template<typename Vector> +static void AddLazyVectorDecls(ASTWriter &Writer, Vector &Vec, + ASTWriter::RecordData &Record) { + for (typename Vector::iterator I = Vec.begin(0, true), E = Vec.end(); + I != E; ++I) { + Writer.AddDeclRef(*I, Record); + } +} + void ASTWriter::WriteASTCore(Sema &SemaRef, MemorizeStatCalls *StatCalls, StringRef isysroot, const std::string &OutputFile) { @@ -2805,17 +2814,12 @@ void ASTWriter::WriteASTCore(Sema &SemaRef, MemorizeStatCalls *StatCalls, // TentativeDefinitions order. Generally, this record will be empty for // headers. RecordData TentativeDefinitions; - for (Sema::TentativeDefinitionsType::iterator - T = SemaRef.TentativeDefinitions.begin(0, true), - TEnd = SemaRef.TentativeDefinitions.end(); - T != TEnd; ++T) { - AddDeclRef(*T, TentativeDefinitions); - } + AddLazyVectorDecls(*this, SemaRef.TentativeDefinitions, TentativeDefinitions); // Build a record containing all of the file scoped decls in this file. RecordData UnusedFileScopedDecls; - for (unsigned i=0, e = SemaRef.UnusedFileScopedDecls.size(); i !=e; ++i) - AddDeclRef(SemaRef.UnusedFileScopedDecls[i], UnusedFileScopedDecls); + AddLazyVectorDecls(*this, SemaRef.UnusedFileScopedDecls, + UnusedFileScopedDecls); RecordData DelegatingCtorDecls; for (unsigned i=0, e = SemaRef.DelegatingCtorDecls.size(); i != e; ++i) @@ -3075,19 +3079,12 @@ void ASTWriter::WriteASTChain(Sema &SemaRef, MemorizeStatCalls *StatCalls, // Build a record containing all of the new tentative definitions in this // file, in TentativeDefinitions order. RecordData TentativeDefinitions; - for (Sema::TentativeDefinitionsType::iterator - T = SemaRef.TentativeDefinitions.begin(0, true), - TEnd = SemaRef.TentativeDefinitions.end(); - T != TEnd; ++T) { - AddDeclRef(*T, TentativeDefinitions); - } + AddLazyVectorDecls(*this, SemaRef.TentativeDefinitions, TentativeDefinitions); // Build a record containing all of the file scoped decls in this file. RecordData UnusedFileScopedDecls; - for (unsigned i=0, e = SemaRef.UnusedFileScopedDecls.size(); i !=e; ++i) { - if (SemaRef.UnusedFileScopedDecls[i]->getPCHLevel() == 0) - AddDeclRef(SemaRef.UnusedFileScopedDecls[i], UnusedFileScopedDecls); - } + AddLazyVectorDecls(*this, SemaRef.UnusedFileScopedDecls, + UnusedFileScopedDecls); // Build a record containing all of the delegating constructor decls in this // file. |