[cfe-commits] r143037 - in /cfe/trunk: lib/Serialization/ASTReaderDecl.cpp lib/Serialization/ASTWriterDecl.cpp test/Index/Inputs/redeclarations.h test/Index/redeclarations.cpp
Douglas Gregor
dgregor at apple.com
Wed Oct 26 10:53:41 PDT 2011
Author: dgregor
Date: Wed Oct 26 12:53:41 2011
New Revision: 143037
URL: http://llvm.org/viewvc/llvm-project?rev=143037&view=rev
Log:
Eliminate a hang while loading a sequence of redeclarable entities. In
essence, the redeclaration chain for a class could end up in an
inconsistent state while deserializing multiple declarations in that
chain, where the circular linked list was not, in fact,
circular. Since only two redeclarations of the same entity will get
loaded when we're in this state, restore circularity when both have
been loaded. Fixes <rdar://problem/10324940> / PR11195.
Added:
cfe/trunk/test/Index/Inputs/redeclarations.h (with props)
cfe/trunk/test/Index/redeclarations.cpp (with props)
Modified:
cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=143037&r1=143036&r2=143037&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Wed Oct 26 12:53:41 2011
@@ -278,8 +278,8 @@
}
void ASTDeclReader::VisitTagDecl(TagDecl *TD) {
- VisitTypeDecl(TD);
VisitRedeclarable(TD);
+ VisitTypeDecl(TD);
TD->IdentifierNamespace = Record[Idx++];
TD->setTagKind((TagDecl::TagKind)Record[Idx++]);
TD->setCompleteDefinition(Record[Idx++]);
@@ -340,8 +340,8 @@
}
void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
- VisitDeclaratorDecl(FD);
VisitRedeclarable(FD);
+ VisitDeclaratorDecl(FD);
ReadDeclarationNameLoc(FD->DNLoc, FD->getDeclName(), Record, Idx);
FD->IdentifierNamespace = Record[Idx++];
@@ -712,8 +712,8 @@
}
void ASTDeclReader::VisitVarDecl(VarDecl *VD) {
- VisitDeclaratorDecl(VD);
VisitRedeclarable(VD);
+ VisitDeclaratorDecl(VD);
VD->VarDeclBits.SClass = (StorageClass)Record[Idx++];
VD->VarDeclBits.SClassAsWritten = (StorageClass)Record[Idx++];
VD->VarDeclBits.ThreadSpecified = Record[Idx++];
@@ -1329,18 +1329,37 @@
// 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(FirstDeclID)));
+ T *FirstDecl = cast_or_null<T>(Reader.GetDecl(FirstDeclID));
+ D->RedeclLink = typename Redeclarable<T>::PreviousDeclLink(FirstDecl);
if (PreviousDeclID != FirstDeclID)
Reader.PendingPreviousDecls.push_back(std::make_pair(static_cast<T*>(D),
PreviousDeclID));
+
+ // If the first declaration in the chain is in an inconsistent
+ // state where it thinks that it is the only declaration, fix its
+ // redeclaration link now to point at this declaration, so that we have a
+ // proper redeclaration chain.
+ if (FirstDecl->RedeclLink.getPointer() == FirstDecl) {
+ FirstDecl->RedeclLink
+ = typename Redeclarable<T>::LatestDeclLink(static_cast<T*>(D));
+ }
break;
}
- case PointsToLatest:
- D->RedeclLink = typename Redeclarable<T>::LatestDeclLink(
- ReadDeclAs<T>(Record, Idx));
+ case PointsToLatest: {
+ T *LatestDecl = ReadDeclAs<T>(Record, Idx);
+ D->RedeclLink = typename Redeclarable<T>::LatestDeclLink(LatestDecl);
+
+ // If the latest declaration in the chain is in an inconsistent
+ // state where it thinks that it is the only declaration, fix its
+ // redeclaration link now to point at this declaration, so that we have a
+ // proper redeclaration chain.
+ if (LatestDecl->RedeclLink.getPointer() == LatestDecl) {
+ LatestDecl->RedeclLink
+ = typename Redeclarable<T>::PreviousDeclLink(static_cast<T*>(D));
+ }
break;
}
+ }
assert(!(Kind == PointsToPrevious &&
Reader.FirstLatestDeclIDs.find(ThisDeclID) !=
Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=143037&r1=143036&r2=143037&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Wed Oct 26 12:53:41 2011
@@ -198,8 +198,8 @@
}
void ASTDeclWriter::VisitTagDecl(TagDecl *D) {
- VisitTypeDecl(D);
VisitRedeclarable(D);
+ VisitTypeDecl(D);
Record.push_back(D->getIdentifierNamespace());
Record.push_back((unsigned)D->getTagKind()); // FIXME: stable encoding
Record.push_back(D->isCompleteDefinition());
@@ -289,8 +289,8 @@
}
void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
- VisitDeclaratorDecl(D);
VisitRedeclarable(D);
+ VisitDeclaratorDecl(D);
Writer.AddDeclarationNameLoc(D->DNLoc, D->getDeclName(), Record);
Record.push_back(D->getIdentifierNamespace());
@@ -651,8 +651,8 @@
}
void ASTDeclWriter::VisitVarDecl(VarDecl *D) {
- VisitDeclaratorDecl(D);
VisitRedeclarable(D);
+ VisitDeclaratorDecl(D);
Record.push_back(D->getStorageClass()); // FIXME: stable encoding
Record.push_back(D->getStorageClassAsWritten());
Record.push_back(D->isThreadSpecified());
@@ -1336,6 +1336,8 @@
// Abbreviation for DECL_ENUM
Abv = new BitCodeAbbrev();
Abv->Add(BitCodeAbbrevOp(serialization::DECL_ENUM));
+ // Redeclarable
+ Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration
// Decl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext
@@ -1353,8 +1355,6 @@
// TypeDecl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type Ref
- // Redeclarable
- Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration
// TagDecl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // IdentifierNamespace
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getTagKind
@@ -1382,6 +1382,8 @@
// Abbreviation for DECL_RECORD
Abv = new BitCodeAbbrev();
Abv->Add(BitCodeAbbrevOp(serialization::DECL_RECORD));
+ // Redeclarable
+ Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration
// Decl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext
@@ -1399,8 +1401,6 @@
// TypeDecl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type Ref
- // Redeclarable
- Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration
// TagDecl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // IdentifierNamespace
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getTagKind
@@ -1422,6 +1422,8 @@
// Abbreviation for DECL_PARM_VAR
Abv = new BitCodeAbbrev();
Abv->Add(BitCodeAbbrevOp(serialization::DECL_PARM_VAR));
+ // Redeclarable
+ Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration
// Decl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext
@@ -1442,7 +1444,6 @@
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InnerStartLoc
Abv->Add(BitCodeAbbrevOp(0)); // hasExtInfo
// VarDecl
- Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration
Abv->Add(BitCodeAbbrevOp(0)); // StorageClass
Abv->Add(BitCodeAbbrevOp(0)); // StorageClassAsWritten
Abv->Add(BitCodeAbbrevOp(0)); // isThreadSpecified
@@ -1495,6 +1496,8 @@
// Abbreviation for DECL_VAR
Abv = new BitCodeAbbrev();
Abv->Add(BitCodeAbbrevOp(serialization::DECL_VAR));
+ // Redeclarable
+ Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration
// Decl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext
@@ -1515,7 +1518,6 @@
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InnerStartLoc
Abv->Add(BitCodeAbbrevOp(0)); // hasExtInfo
// VarDecl
- Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // StorageClass
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // StorageClassAsWritten
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isThreadSpecified
Added: cfe/trunk/test/Index/Inputs/redeclarations.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/Inputs/redeclarations.h?rev=143037&view=auto
==============================================================================
--- cfe/trunk/test/Index/Inputs/redeclarations.h (added)
+++ cfe/trunk/test/Index/Inputs/redeclarations.h Wed Oct 26 12:53:41 2011
@@ -0,0 +1,21 @@
+class X
+{
+ friend class A;
+};
+
+
+template <typename T1, typename T2>
+class B
+{
+};
+
+template <class T>
+struct C
+{
+};
+
+class D
+{
+ B<D, class A> x;
+ friend struct C<A>;
+};
Propchange: cfe/trunk/test/Index/Inputs/redeclarations.h
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cfe/trunk/test/Index/Inputs/redeclarations.h
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: cfe/trunk/test/Index/Inputs/redeclarations.h
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: cfe/trunk/test/Index/redeclarations.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/redeclarations.cpp?rev=143037&view=auto
==============================================================================
--- cfe/trunk/test/Index/redeclarations.cpp (added)
+++ cfe/trunk/test/Index/redeclarations.cpp Wed Oct 26 12:53:41 2011
@@ -0,0 +1,21 @@
+#include "redeclarations.h"
+
+class A
+{
+};
+
+// RUN: env CINDEXTEST_EDITING=1 c-index-test -test-load-source-reparse 2 all -I%S/Inputs %s | FileCheck %s
+
+// CHECK: redeclarations.h:1:7: ClassDecl=X:1:7 (Definition) Extent=[1:1 - 4:2]
+// CHECK: redeclarations.h:8:7: ClassTemplate=B:8:7 (Definition) Extent=[7:1 - 10:2]
+// CHECK: redeclarations.h:7:20: TemplateTypeParameter=T1:7:20 (Definition) Extent=[7:11 - 7:22]
+// CHECK: redeclarations.h:7:33: TemplateTypeParameter=T2:7:33 (Definition) Extent=[7:24 - 7:35]
+// CHECK: redeclarations.h:13:8: ClassTemplate=C:13:8 (Definition) Extent=[12:1 - 15:2]
+// CHECK: redeclarations.h:12:17: TemplateTypeParameter=T:12:17 (Definition) Extent=[12:11 - 12:18]
+// CHECK: redeclarations.h:17:7: ClassDecl=D:17:7 (Definition) Extent=[17:1 - 21:2]
+// CHECK: redeclarations.h:19:16: ClassDecl=A:19:16 Extent=[19:10 - 19:17]
+// CHECK: redeclarations.h:19:19: FieldDecl=x:19:19 (Definition) Extent=[19:5 - 19:20]
+// CHECK: redeclarations.h:19:5: TemplateRef=B:8:7 Extent=[19:5 - 19:6]
+// CHECK: redeclarations.h:19:7: TypeRef=class D:17:7 Extent=[19:7 - 19:8]
+// CHECK: redeclarations.h:19:16: TypeRef=class A:3:7 Extent=[19:16 - 19:17]
+// CHECK: redeclarations.cpp:3:7: ClassDecl=A:3:7 (Definition) Extent=[3:1 - 5:2]
Propchange: cfe/trunk/test/Index/redeclarations.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cfe/trunk/test/Index/redeclarations.cpp
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: cfe/trunk/test/Index/redeclarations.cpp
------------------------------------------------------------------------------
svn:mime-type = text/plain
More information about the cfe-commits
mailing list