summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2011-10-07 21:55:43 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2011-10-07 21:55:43 +0000
commitec2ec1f20322076717c3865b196f7a1c95d883a4 (patch)
treeae7edbbe553f80a9efb884da59612946c7e19750
parent3f5e8d87dbf449d8b39fe96068415428594d370e (diff)
In DeclContext::LoadLexicalDeclsFromExternalStorage don't clear out
the fields if they are already loaded, just ignore them when we are building the chain in BuildDeclChain. This fixes an lldb issue where fields were removed and not getting re-added because lldb is based on ASTImporter adding decls to DeclContext and fields were already added before by the ASTImporter. We should really simplify the interaction between DeclContext <-> lldb going forward.. rdar://10246067 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@141418 91177308-0d34-0410-b5e6-96231b3b80d8
-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)