]> granicus.if.org Git - clang/commitdiff
In DeclContext::LoadLexicalDeclsFromExternalStorage don't clear out
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Fri, 7 Oct 2011 21:55:43 +0000 (21:55 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Fri, 7 Oct 2011 21:55:43 +0000 (21:55 +0000)
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

include/clang/AST/DeclBase.h
lib/AST/Decl.cpp
lib/AST/DeclBase.cpp

index 7e093c8ceb909370b7aed28f58328a6f23a2aab6..25a103a767c6639f409b7c993e4465b645c0fcef 100644 (file)
@@ -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),
index 9e6947d5e3ab3e09e52e6329b45327169591d63b..7d3390f133410e56bb22c585f4df27d09436a9e1 100644 (file)
@@ -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);
 }
 
 //===----------------------------------------------------------------------===//
index d0afcbc45b56da26041b2b386c0ae237db782846..844a39361bed205e432616aafd6fbb3f2974832c 100644 (file)
@@ -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)