[llvm-branch-commits] [cfe-branch] r125835 - in /cfe/branches/Apple/whitney: include/clang/Serialization/ASTReader.h lib/Serialization/ASTReader.cpp lib/Serialization/ASTReaderDecl.cpp lib/Serialization/ASTWriterDecl.cpp test/Index/c-index-redecls.c

Daniel Dunbar daniel at zuster.org
Fri Feb 18 07:47:48 PST 2011


Author: ddunbar
Date: Fri Feb 18 09:47:48 2011
New Revision: 125835

URL: http://llvm.org/viewvc/llvm-project?rev=125835&view=rev
Log:
Merge r125434:
--
Author: Argyrios Kyrtzidis <akyrtzi at gmail.com>
Date:   Sat Feb 12 07:50:47 2011 +0000

    When reading the AST, delay loading of the redeclaration chain to avoid deeply nested calls.
    Temporarily set the first (canonical) declaration as the previous one, which is the one that
    matters, and mark the real previous DeclID to be loaded & attached later on.

    Fixes rdar://8956193.

Added:
    cfe/branches/Apple/whitney/test/Index/c-index-redecls.c
Modified:
    cfe/branches/Apple/whitney/include/clang/Serialization/ASTReader.h
    cfe/branches/Apple/whitney/lib/Serialization/ASTReader.cpp
    cfe/branches/Apple/whitney/lib/Serialization/ASTReaderDecl.cpp
    cfe/branches/Apple/whitney/lib/Serialization/ASTWriterDecl.cpp

Modified: cfe/branches/Apple/whitney/include/clang/Serialization/ASTReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney/include/clang/Serialization/ASTReader.h?rev=125835&r1=125834&r2=125835&view=diff
==============================================================================
--- cfe/branches/Apple/whitney/include/clang/Serialization/ASTReader.h (original)
+++ cfe/branches/Apple/whitney/include/clang/Serialization/ASTReader.h Fri Feb 18 09:47:48 2011
@@ -686,6 +686,13 @@
   /// Objective-C protocols.
   std::deque<Decl *> InterestingDecls;
 
+  /// \brief We delay loading of the previous declaration chain to avoid
+  /// deeply nested calls when there are many redeclarations.
+  std::deque<std::pair<Decl *, serialization::DeclID> > PendingPreviousDecls;
+
+  /// \brief Ready to load the previous declaration of the given Decl.
+  void loadAndAttachPreviousDecl(Decl *D, serialization::DeclID ID);
+
   /// \brief When reading a Stmt tree, Stmt operands are placed in this stack.
   llvm::SmallVector<Stmt *, 16> StmtStack;
 

Modified: cfe/branches/Apple/whitney/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney/lib/Serialization/ASTReader.cpp?rev=125835&r1=125834&r2=125835&view=diff
==============================================================================
--- cfe/branches/Apple/whitney/lib/Serialization/ASTReader.cpp (original)
+++ cfe/branches/Apple/whitney/lib/Serialization/ASTReader.cpp Fri Feb 18 09:47:48 2011
@@ -4514,6 +4514,13 @@
       PendingIdentifierInfos.pop_front();
     }
 
+    // Ready to load previous declarations of Decls that were delayed.
+    while (!PendingPreviousDecls.empty()) {
+      loadAndAttachPreviousDecl(PendingPreviousDecls.front().first,
+                                PendingPreviousDecls.front().second);
+      PendingPreviousDecls.pop_front();
+    }
+
     // We are not in recursive loading, so it's safe to pass the "interesting"
     // decls to the consumer.
     if (Consumer)

Modified: cfe/branches/Apple/whitney/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney/lib/Serialization/ASTReaderDecl.cpp?rev=125835&r1=125834&r2=125835&view=diff
==============================================================================
--- cfe/branches/Apple/whitney/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/branches/Apple/whitney/lib/Serialization/ASTReaderDecl.cpp Fri Feb 18 09:47:48 2011
@@ -75,6 +75,8 @@
       : Reader(Reader), F(F), Cursor(Cursor), ThisDeclID(thisDeclID),
         Record(Record), Idx(Idx), TypeIDForTypeDecl(0) { }
 
+    static void attachPreviousDecl(Decl *D, Decl *previous);
+
     void Visit(Decl *D);
 
     void UpdateDecl(Decl *D, const RecordData &Record);
@@ -951,13 +953,22 @@
   // can be used while this is still initializing.
 
   assert(D->CommonOrPrev.isNull() && "getCommonPtr was called earlier on this");
-  RedeclarableTemplateDecl *PrevDecl =
-      cast_or_null<RedeclarableTemplateDecl>(Reader.GetDecl(Record[Idx++]));
-  assert((PrevDecl == 0 || PrevDecl->getKind() == D->getKind()) &&
-         "PrevDecl kind mismatch");
-  if (PrevDecl)
-    D->CommonOrPrev = PrevDecl;
-  if (PrevDecl == 0) {
+  DeclID PreviousDeclID = Record[Idx++];
+  DeclID FirstDeclID =  PreviousDeclID ? Record[Idx++] : 0;
+  // We delay loading of the redeclaration chain to avoid deeply nested calls.
+  // We temporarily set the first (canonical) declaration as the previous one
+  // which is the one that matters and mark the real previous DeclID to be
+  // loaded & attached later on.
+  RedeclarableTemplateDecl *FirstDecl =
+      cast_or_null<RedeclarableTemplateDecl>(Reader.GetDecl(FirstDeclID));
+  assert((FirstDecl == 0 || FirstDecl->getKind() == D->getKind()) &&
+         "FirstDecl kind mismatch");
+  if (FirstDecl) {
+    D->CommonOrPrev = FirstDecl;
+    // Mark the real previous DeclID to be loaded & attached later on.
+    if (PreviousDeclID != FirstDeclID)
+      Reader.PendingPreviousDecls.push_back(std::make_pair(D, PreviousDeclID));
+  } else {
     D->CommonOrPrev = D->newCommon(*Reader.getContext());
     if (RedeclarableTemplateDecl *RTD
           = cast_or_null<RedeclarableTemplateDecl>(Reader.GetDecl(Record[Idx++]))) {
@@ -1182,10 +1193,20 @@
                 " reading");
   case NoRedeclaration:
     break;
-  case PointsToPrevious:
+  case PointsToPrevious: {
+    DeclID PreviousDeclID = Record[Idx++];
+    DeclID FirstDeclID = Record[Idx++];
+    // We delay loading of the redeclaration chain to avoid deeply nested calls.
+    // We temporarily set the first (canonical) declaration as the previous one
+    // which is the one that matters and mark the real previous DeclID to be
+    // loaded & attached later on.
     D->RedeclLink = typename Redeclarable<T>::PreviousDeclLink(
-                                cast_or_null<T>(Reader.GetDecl(Record[Idx++])));
+                                cast_or_null<T>(Reader.GetDecl(FirstDeclID)));
+    if (PreviousDeclID != FirstDeclID)
+      Reader.PendingPreviousDecls.push_back(std::make_pair(static_cast<T*>(D),
+                                                           PreviousDeclID));
     break;
+  }
   case PointsToLatest:
     D->RedeclLink = typename Redeclarable<T>::LatestDeclLink(
                                 cast_or_null<T>(Reader.GetDecl(Record[Idx++])));
@@ -1287,6 +1308,25 @@
   return RecordLocation(F, F->DeclOffsets[Index]);
 }
 
+void ASTDeclReader::attachPreviousDecl(Decl *D, Decl *previous) {
+  assert(D && previous);
+  if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
+    TD->RedeclLink.setPointer(cast<TagDecl>(previous));
+  } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+    FD->RedeclLink.setPointer(cast<FunctionDecl>(previous));
+  } else if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
+    VD->RedeclLink.setPointer(cast<VarDecl>(previous));
+  } else {
+    RedeclarableTemplateDecl *TD = cast<RedeclarableTemplateDecl>(D);
+    TD->CommonOrPrev = cast<RedeclarableTemplateDecl>(previous);
+  }
+}
+
+void ASTReader::loadAndAttachPreviousDecl(Decl *D, serialization::DeclID ID) {
+  Decl *previous = GetDecl(ID);
+  ASTDeclReader::attachPreviousDecl(D, previous);
+}
+
 /// \brief Read the declaration at the given offset from the AST file.
 Decl *ASTReader::ReadDeclRecord(unsigned Index, DeclID ID) {
   RecordLocation Loc = DeclCursorForIndex(Index, ID);

Modified: cfe/branches/Apple/whitney/lib/Serialization/ASTWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney/lib/Serialization/ASTWriterDecl.cpp?rev=125835&r1=125834&r2=125835&view=diff
==============================================================================
--- cfe/branches/Apple/whitney/lib/Serialization/ASTWriterDecl.cpp (original)
+++ cfe/branches/Apple/whitney/lib/Serialization/ASTWriterDecl.cpp Fri Feb 18 09:47:48 2011
@@ -834,6 +834,9 @@
   // getCommonPtr() can be used while this is still initializing.
 
   Writer.AddDeclRef(D->getPreviousDeclaration(), Record);
+  if (D->getPreviousDeclaration())
+    Writer.AddDeclRef(D->getFirstDeclaration(), Record);
+
   if (D->getPreviousDeclaration() == 0) {
     // This TemplateDecl owns the CommonPtr; write it.
     assert(D->isCanonicalDecl());
@@ -1030,9 +1033,14 @@
   if (D->RedeclLink.getNext() == D) {
     Record.push_back(NoRedeclaration);
   } else {
-    Record.push_back(D->RedeclLink.NextIsPrevious() ? PointsToPrevious
-                                                    : PointsToLatest);
-    Writer.AddDeclRef(D->RedeclLink.getPointer(), Record);
+    if (D->RedeclLink.NextIsPrevious()) {
+      Record.push_back(PointsToPrevious);
+      Writer.AddDeclRef(D->getPreviousDeclaration(), Record);
+      Writer.AddDeclRef(D->getFirstDeclaration(), Record);
+    } else {
+      Record.push_back(PointsToLatest);
+      Writer.AddDeclRef(D->RedeclLink.getPointer(), Record);
+    }
   }
 
   T *First = D->getFirstDeclaration();

Added: cfe/branches/Apple/whitney/test/Index/c-index-redecls.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney/test/Index/c-index-redecls.c?rev=125835&view=auto
==============================================================================
--- cfe/branches/Apple/whitney/test/Index/c-index-redecls.c (added)
+++ cfe/branches/Apple/whitney/test/Index/c-index-redecls.c Fri Feb 18 09:47:48 2011
@@ -0,0 +1,107 @@
+// RUN: %clang_cc1 -emit-pch -o %t.ast %s
+// RUN: c-index-test -test-load-tu %t.ast all
+
+// rdar://8956193 - We would blow the thread stack because of nested calls due
+//                  to redeclarations.
+
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);
+void socrates(void);





More information about the llvm-branch-commits mailing list