From: Argyrios Kyrtzidis Date: Wed, 20 Oct 2010 00:11:15 +0000 (+0000) Subject: Fix issue with chained PCH where forward references did not pick up later definition... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9703b0dd353b928b2312076f13e30950e05d5fa1;p=clang Fix issue with chained PCH where forward references did not pick up later definition in the chained PCH. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@116887 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp index bcef244723..38672a6536 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/lib/Serialization/ASTReaderDecl.cpp @@ -788,6 +788,24 @@ void ASTDeclReader::VisitCXXRecordDecl(CXXRecordDecl *D) { VisitRecordDecl(D); + if (D->DefinitionData) { + // Synchronize the DefinitionData pointer among all redeclarations. + // This synchronization ends up being done multiple times but it's necessary + // because a chained PCH may introduce a definition that earlier + // redeclarations in another PCH have no information about. + llvm::SmallPtrSet PrevRedecls; + PrevRedecls.insert(D); + CXXRecordDecl *Redecl = cast(D->RedeclLink.getNext()); + while (!PrevRedecls.count(Redecl)) { + PrevRedecls.insert(Redecl); + assert((!Redecl->DefinitionData || + Redecl->DefinitionData == D->DefinitionData) && + "Multiple definitions in the redeclaration chain ?"); + Redecl->DefinitionData = D->DefinitionData; + Redecl = cast(Redecl->RedeclLink.getNext()); + } + } + if (OwnsDefinitionData) { assert(D->DefinitionData); struct CXXRecordDecl::DefinitionData &Data = *D->DefinitionData; diff --git a/test/PCH/chain-cxx.cpp b/test/PCH/chain-cxx.cpp index b2d0523410..d269de529f 100644 --- a/test/PCH/chain-cxx.cpp +++ b/test/PCH/chain-cxx.cpp @@ -31,6 +31,9 @@ struct S { typedef int G; }; template struct S { typedef int H; }; +template struct TS2; +typedef TS2 TS2int; + //===----------------------------------------------------------------------===// #elif not defined(HEADER2) #define HEADER2 @@ -68,6 +71,8 @@ struct S { typedef int K; }; template <> struct S { typedef int L; }; +template struct TS2 { }; + //===----------------------------------------------------------------------===// #else //===----------------------------------------------------------------------===// @@ -89,6 +94,8 @@ void test() { typedef S::J T4; typedef S::K T5; typedef S::L T6; + + TS2int ts2; } //===----------------------------------------------------------------------===//