From 3d0adb3201ebdaedcec8d7eecc445df5eb649ae6 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Fri, 15 Jul 2011 21:46:17 +0000 Subject: [PATCH] Augment the interface of ExternalASTSource::FindExternalLexicalDecls() to allow clients to specify that they've already (correctly) loaded declarations, and that no further action is needed. Also, make sure that we clear the "has external lexical declarations" bit before calling FindExternalLexicalDecls(), to avoid infinite recursion. llvm-svn: 135306 --- clang/include/clang/AST/ExternalASTSource.h | 24 +++++++++++++++---- clang/include/clang/Serialization/ASTReader.h | 2 +- .../Serialization/ChainedIncludesSource.h | 2 +- clang/lib/AST/Decl.cpp | 11 ++++++--- clang/lib/AST/DeclBase.cpp | 13 ++++++---- clang/lib/AST/ExternalASTSource.cpp | 4 ++-- clang/lib/Serialization/ASTReader.cpp | 7 ++---- .../Serialization/ChainedIncludesSource.cpp | 3 ++- 8 files changed, 44 insertions(+), 22 deletions(-) diff --git a/clang/include/clang/AST/ExternalASTSource.h b/clang/include/clang/AST/ExternalASTSource.h index 846813adf7c3..ef1f1618ba1d 100644 --- a/clang/include/clang/AST/ExternalASTSource.h +++ b/clang/include/clang/AST/ExternalASTSource.h @@ -32,6 +32,20 @@ class Selector; class Stmt; class TagDecl; +/// \brief Enumeration describing the result of loading information from +/// an external source. +enum ExternalLoadResult { + /// \brief Loading the external information has succeeded. + ELR_Success, + + /// \brief Loading the external information has failed. + ELR_Failure, + + /// \brief The external information has already been loaded, and therefore + /// no additional processing is required. + ELR_AlreadyLoaded +}; + /// \brief Abstract interface for external sources of AST nodes. /// /// External AST sources provide AST nodes constructed from some @@ -132,10 +146,10 @@ public: /// declaration kind is one we are looking for. If NULL, all declarations /// are returned. /// - /// \return true if an error occurred + /// \return an indication of whether the load succeeded or failed. /// /// The default implementation of this method is a no-op. - virtual bool FindExternalLexicalDecls(const DeclContext *DC, + virtual ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC, bool (*isKindWeWant)(Decl::Kind), llvm::SmallVectorImpl &Result); @@ -143,14 +157,14 @@ public: /// DeclContext. /// /// \return true if an error occurred - bool FindExternalLexicalDecls(const DeclContext *DC, + ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC, llvm::SmallVectorImpl &Result) { return FindExternalLexicalDecls(DC, 0, Result); } template - bool FindExternalLexicalDeclsBy(const DeclContext *DC, - llvm::SmallVectorImpl &Result) { + ExternalLoadResult FindExternalLexicalDeclsBy(const DeclContext *DC, + llvm::SmallVectorImpl &Result) { return FindExternalLexicalDecls(DC, DeclTy::classofKind, Result); } diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index a6c32aafd335..9e210c3db28c 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/include/clang/Serialization/ASTReader.h @@ -1070,7 +1070,7 @@ public: /// /// \returns true if there was an error while reading the /// declarations for this declaration context. - virtual bool FindExternalLexicalDecls(const DeclContext *DC, + virtual ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC, bool (*isKindWeWant)(Decl::Kind), llvm::SmallVectorImpl &Decls); diff --git a/clang/include/clang/Serialization/ChainedIncludesSource.h b/clang/include/clang/Serialization/ChainedIncludesSource.h index 0c3e86faf414..f547902ef0eb 100644 --- a/clang/include/clang/Serialization/ChainedIncludesSource.h +++ b/clang/include/clang/Serialization/ChainedIncludesSource.h @@ -47,7 +47,7 @@ protected: virtual DeclContextLookupResult FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name); virtual void MaterializeVisibleDecls(const DeclContext *DC); - virtual bool FindExternalLexicalDecls(const DeclContext *DC, + virtual ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC, bool (*isKindWeWant)(Decl::Kind), llvm::SmallVectorImpl &Result); virtual void CompleteType(TagDecl *Tag); diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 9b507cfc5e24..4c323da7eee3 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -2361,8 +2361,15 @@ void RecordDecl::LoadFieldsFromExternalStorage() const { ExternalASTSource::Deserializing TheFields(Source); llvm::SmallVector Decls; - if (Source->FindExternalLexicalDeclsBy(this, Decls)) + LoadedFieldsFromExternalStorage = true; + switch (Source->FindExternalLexicalDeclsBy(this, Decls)) { + case ELR_Success: + break; + + case ELR_AlreadyLoaded: + case ELR_Failure: return; + } #ifndef NDEBUG // Check that all decls we got were FieldDecls. @@ -2370,8 +2377,6 @@ void RecordDecl::LoadFieldsFromExternalStorage() const { assert(isa(Decls[i])); #endif - LoadedFieldsFromExternalStorage = true; - if (Decls.empty()) return; diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index 7d146572bf6d..b2806f092cbd 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -839,12 +839,17 @@ DeclContext::LoadLexicalDeclsFromExternalStorage() const { // Notify that we have a DeclContext that is initializing. ExternalASTSource::Deserializing ADeclContext(Source); + // Load the external declarations, if any. llvm::SmallVector Decls; - if (Source->FindExternalLexicalDecls(this, Decls)) - return; - - // There is no longer any lexical storage in this context ExternalLexicalStorage = false; + switch (Source->FindExternalLexicalDecls(this, Decls)) { + case ELR_Success: + break; + + case ELR_Failure: + case ELR_AlreadyLoaded: + return; + } if (Decls.empty()) return; diff --git a/clang/lib/AST/ExternalASTSource.cpp b/clang/lib/AST/ExternalASTSource.cpp index f428318a21e3..b96d65a729ca 100644 --- a/clang/lib/AST/ExternalASTSource.cpp +++ b/clang/lib/AST/ExternalASTSource.cpp @@ -51,11 +51,11 @@ ExternalASTSource::FindExternalVisibleDeclsByName(const DeclContext *DC, void ExternalASTSource::MaterializeVisibleDecls(const DeclContext *DC) { } -bool +ExternalLoadResult ExternalASTSource::FindExternalLexicalDecls(const DeclContext *DC, bool (*isKindWeWant)(Decl::Kind), llvm::SmallVectorImpl &Result) { - return true; + return ELR_AlreadyLoaded; } void ExternalASTSource::getMemoryBufferSizes(MemoryBufferSizes &sizes) const { } diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 13933b3eb3f2..a4ed5f4da48c 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -4008,12 +4008,9 @@ Stmt *ASTReader::GetExternalDeclStmt(uint64_t Offset) { llvm_unreachable("Broken chain"); } -bool ASTReader::FindExternalLexicalDecls(const DeclContext *DC, +ExternalLoadResult ASTReader::FindExternalLexicalDecls(const DeclContext *DC, bool (*isKindWeWant)(Decl::Kind), llvm::SmallVectorImpl &Decls) { - assert(DC->hasExternalLexicalStorage() && - "DeclContext has no lexical decls in storage"); - // There might be lexical decls in multiple parts of the chain, for the TU // at least. // DeclContextOffsets might reallocate as we load additional decls below, @@ -4038,7 +4035,7 @@ bool ASTReader::FindExternalLexicalDecls(const DeclContext *DC, } ++NumLexicalDeclContextsRead; - return false; + return ELR_Success; } DeclContext::lookup_result diff --git a/clang/lib/Serialization/ChainedIncludesSource.cpp b/clang/lib/Serialization/ChainedIncludesSource.cpp index da5be957a530..3b7cd23b92ae 100644 --- a/clang/lib/Serialization/ChainedIncludesSource.cpp +++ b/clang/lib/Serialization/ChainedIncludesSource.cpp @@ -185,7 +185,8 @@ ChainedIncludesSource::FindExternalVisibleDeclsByName(const DeclContext *DC, void ChainedIncludesSource::MaterializeVisibleDecls(const DeclContext *DC) { return getFinalReader().MaterializeVisibleDecls(DC); } -bool ChainedIncludesSource::FindExternalLexicalDecls(const DeclContext *DC, +ExternalLoadResult +ChainedIncludesSource::FindExternalLexicalDecls(const DeclContext *DC, bool (*isKindWeWant)(Decl::Kind), llvm::SmallVectorImpl &Result) { return getFinalReader().FindExternalLexicalDecls(DC, isKindWeWant, Result);