aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/AST/DeclBase.h2
-rw-r--r--lib/AST/Decl.cpp3
-rw-r--r--lib/AST/DeclBase.cpp31
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)