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);