diff options
-rw-r--r-- | include/clang/AST/DeclBase.h | 2 | ||||
-rw-r--r-- | lib/AST/Decl.cpp | 3 | ||||
-rw-r--r-- | lib/AST/DeclBase.cpp | 31 |
3 files changed, 16 insertions, 20 deletions
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h index 7e093c8ceb..25a103a767 100644 --- a/include/clang/AST/DeclBase.h +++ b/include/clang/AST/DeclBase.h @@ -846,7 +846,7 @@ protected: /// /// \returns the first/last pair of declarations. static std::pair<Decl *, Decl *> - BuildDeclChain(const SmallVectorImpl<Decl*> &Decls); + BuildDeclChain(const SmallVectorImpl<Decl*> &Decls, bool FieldsAlreadyLoaded); DeclContext(Decl::Kind K) : DeclKind(K), ExternalLexicalStorage(false), diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 9e6947d5e3..7d3390f133 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -2432,7 +2432,8 @@ void RecordDecl::LoadFieldsFromExternalStorage() const { if (Decls.empty()) return; - llvm::tie(FirstDecl, LastDecl) = BuildDeclChain(Decls); + llvm::tie(FirstDecl, LastDecl) = BuildDeclChain(Decls, + /*FieldsAlreadyLoaded=*/false); } //===----------------------------------------------------------------------===// diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp index d0afcbc45b..844a39361b 100644 --- a/lib/AST/DeclBase.cpp +++ b/lib/AST/DeclBase.cpp @@ -816,11 +816,15 @@ DeclContext *DeclContext::getNextContext() { } std::pair<Decl *, Decl *> -DeclContext::BuildDeclChain(const SmallVectorImpl<Decl*> &Decls) { +DeclContext::BuildDeclChain(const SmallVectorImpl<Decl*> &Decls, + bool FieldsAlreadyLoaded) { // Build up a chain of declarations via the Decl::NextDeclInContext field. Decl *FirstNewDecl = 0; Decl *PrevDecl = 0; for (unsigned I = 0, N = Decls.size(); I != N; ++I) { + if (FieldsAlreadyLoaded && isa<FieldDecl>(Decls[I])) + continue; + Decl *D = Decls[I]; if (PrevDecl) PrevDecl->NextDeclInContext = D; @@ -842,22 +846,6 @@ DeclContext::LoadLexicalDeclsFromExternalStorage() const { // Notify that we have a DeclContext that is initializing. ExternalASTSource::Deserializing ADeclContext(Source); - - // We may have already loaded just the fields of this record, in which case - // we remove all of the fields from the list. The fields will be reloaded - // from the external source as part of re-establishing the context. - if (const RecordDecl *RD = dyn_cast<RecordDecl>(this)) { - if (RD->LoadedFieldsFromExternalStorage) { - while (FirstDecl && isa<FieldDecl>(FirstDecl)) { - Decl *Next = FirstDecl->NextDeclInContext; - FirstDecl->NextDeclInContext = 0; - FirstDecl = Next; - } - - if (!FirstDecl) - LastDecl = 0; - } - } // Load the external declarations, if any. SmallVector<Decl*, 64> Decls; @@ -874,10 +862,17 @@ DeclContext::LoadLexicalDeclsFromExternalStorage() const { if (Decls.empty()) return; + // We may have already loaded just the fields of this record, in which case + // we need to ignore them. + bool FieldsAlreadyLoaded = false; + if (const RecordDecl *RD = dyn_cast<RecordDecl>(this)) + FieldsAlreadyLoaded = RD->LoadedFieldsFromExternalStorage; + // Splice the newly-read declarations into the beginning of the list // of declarations. Decl *ExternalFirst, *ExternalLast; - llvm::tie(ExternalFirst, ExternalLast) = BuildDeclChain(Decls); + llvm::tie(ExternalFirst, ExternalLast) = BuildDeclChain(Decls, + FieldsAlreadyLoaded); ExternalLast->NextDeclInContext = FirstDecl; FirstDecl = ExternalFirst; if (!LastDecl) |