[cfe-commits] r141418 - in /cfe/trunk: include/clang/AST/DeclBase.h lib/AST/Decl.cpp lib/AST/DeclBase.cpp

Argyrios Kyrtzidis akyrtzi at gmail.com
Fri Oct 7 14:55:43 PDT 2011


Author: akirtzidis
Date: Fri Oct  7 16:55:43 2011
New Revision: 141418

URL: http://llvm.org/viewvc/llvm-project?rev=141418&view=rev
Log:
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

Modified:
    cfe/trunk/include/clang/AST/DeclBase.h
    cfe/trunk/lib/AST/Decl.cpp
    cfe/trunk/lib/AST/DeclBase.cpp

Modified: cfe/trunk/include/clang/AST/DeclBase.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=141418&r1=141417&r2=141418&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclBase.h (original)
+++ cfe/trunk/include/clang/AST/DeclBase.h Fri Oct  7 16:55:43 2011
@@ -846,7 +846,7 @@
   ///
   /// \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),

Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=141418&r1=141417&r2=141418&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Fri Oct  7 16:55:43 2011
@@ -2432,7 +2432,8 @@
   if (Decls.empty())
     return;
 
-  llvm::tie(FirstDecl, LastDecl) = BuildDeclChain(Decls);
+  llvm::tie(FirstDecl, LastDecl) = BuildDeclChain(Decls,
+                                                 /*FieldsAlreadyLoaded=*/false);
 }
 
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/lib/AST/DeclBase.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=141418&r1=141417&r2=141418&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclBase.cpp (original)
+++ cfe/trunk/lib/AST/DeclBase.cpp Fri Oct  7 16:55:43 2011
@@ -816,11 +816,15 @@
 }
 
 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 @@
 
   // 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 @@
   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)





More information about the cfe-commits mailing list