]> granicus.if.org Git - clang/commitdiff
Fix issue with chained PCH where forward references did not pick up later definition...
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Wed, 20 Oct 2010 00:11:15 +0000 (00:11 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Wed, 20 Oct 2010 00:11:15 +0000 (00:11 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@116887 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Serialization/ASTReaderDecl.cpp
test/PCH/chain-cxx.cpp

index bcef2447235f5ce6a904b36ecc87682dbe60db0a..38672a65366d499231fe47fbbb73a0a1011a49d1 100644 (file)
@@ -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;
index b2d05234106e3be9bb2eaecf5a86fc7d09ab5916..d269de529fba3a4d6ff1a85af2c1bee5e95c9b96 100644 (file)
@@ -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;
 }
 
 //===----------------------------------------------------------------------===//