diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2010-10-20 00:11:15 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2010-10-20 00:11:15 +0000 |
commit | a41f66064f2a524acb8321b4d8a2e883cd1520b4 (patch) | |
tree | 4f28d2985f9eee5bb84ddb0e4c3117f21e1131f7 /clang | |
parent | cb6fc2b2dea4887267b9a23fbea834394688e9cd (diff) | |
download | bcm5719-llvm-a41f66064f2a524acb8321b4d8a2e883cd1520b4.tar.gz bcm5719-llvm-a41f66064f2a524acb8321b4d8a2e883cd1520b4.zip |
Fix issue with chained PCH where forward references did not pick up later definition in the chained PCH.
llvm-svn: 116887
Diffstat (limited to 'clang')
-rw-r--r-- | clang/lib/Serialization/ASTReaderDecl.cpp | 18 | ||||
-rw-r--r-- | clang/test/PCH/chain-cxx.cpp | 7 |
2 files changed, 25 insertions, 0 deletions
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index bcef2447235..38672a65366 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/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<CXXRecordDecl *, 16> PrevRedecls; + PrevRedecls.insert(D); + CXXRecordDecl *Redecl = cast<CXXRecordDecl>(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<CXXRecordDecl>(Redecl->RedeclLink.getNext()); + } + } + if (OwnsDefinitionData) { assert(D->DefinitionData); struct CXXRecordDecl::DefinitionData &Data = *D->DefinitionData; diff --git a/clang/test/PCH/chain-cxx.cpp b/clang/test/PCH/chain-cxx.cpp index b2d05234106..d269de529fb 100644 --- a/clang/test/PCH/chain-cxx.cpp +++ b/clang/test/PCH/chain-cxx.cpp @@ -31,6 +31,9 @@ struct S { typedef int G; }; template <typename T> struct S<T *> { typedef int H; }; +template <typename T> struct TS2; +typedef TS2<int> TS2int; + //===----------------------------------------------------------------------===// #elif not defined(HEADER2) #define HEADER2 @@ -68,6 +71,8 @@ struct S<int *> { typedef int K; }; template <> struct S<int &> { typedef int L; }; +template <typename T> struct TS2 { }; + //===----------------------------------------------------------------------===// #else //===----------------------------------------------------------------------===// @@ -89,6 +94,8 @@ void test() { typedef S<double &>::J T4; typedef S<int *>::K T5; typedef S<int &>::L T6; + + TS2int ts2; } //===----------------------------------------------------------------------===// |