[modules] If we already have a fake definition for one declaration of a class,

don't think we're providing a new one in an update record adding a definition
to another declaration of the same class.

llvm-svn: 228104
This commit is contained in:
Richard Smith 2015-02-04 01:23:46 +00:00
parent fe43aa8d19
commit 7483d20e77
9 changed files with 46 additions and 13 deletions

View File

@ -3648,7 +3648,8 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile,
auto *RD = cast<CXXRecordDecl>(D);
auto *OldDD = RD->DefinitionData.getNotUpdated();
bool HadRealDefinition =
OldDD && !Reader.PendingFakeDefinitionData.count(OldDD);
OldDD && (OldDD->Definition != RD ||
!Reader.PendingFakeDefinitionData.count(OldDD));
ReadCXXRecordDefinition(RD, /*Update*/true);
// Visible update is handled separately.

View File

@ -0,0 +1,9 @@
namespace N {
template <typename> struct A {
int n;
A() : n() {}
};
// Create declaration of A<int>.
typedef A<int> AI;
}

View File

@ -1,6 +0,0 @@
#include "a.h"
// Add update record for definition of A<int> and constructors.
// We need an eagerly-emitted function here to get the problematic
// deserialization ordering.
void foobar() { N::A<int> x; }

View File

@ -0,0 +1,6 @@
#include "a1.h"
// Add update record for definition of A<int> and constructors.
// We need an eagerly-emitted use here to get the problematic
// deserialization ordering.
N::A<int> b1;

View File

@ -0,0 +1,6 @@
#include "a2.h"
// Add update record for definition of A<int> and constructors.
// We need an eagerly-emitted use here to get the problematic
// deserialization ordering.
N::A<int> b2;

View File

@ -11,4 +11,4 @@ namespace N {
}
// Merge in another declaration and update records.
#include "b.h"
#include "b1.h"

View File

@ -1,6 +1,9 @@
module def { header "def.h" export * }
module update { header "update.h" export * }
module a { header "a.h" export * }
module b { header "b.h" export * }
module a1 { header "a1.h" export * }
module a2 { header "a2.h" export * }
module b1 { header "b1.h" export * }
module b2 { header "b2.h" export * }
module merge { header "merge.h" export * }
module c { header "c.h" export * }

View File

@ -1,9 +1,10 @@
// RUN: rm -rf %t
// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/merge-template-members -verify -emit-llvm-only %s
// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/merge-template-members -verify -emit-llvm-only %s -DTEST=1
// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/merge-template-members -verify -emit-llvm-only %s -DTEST=2
// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/merge-template-members -verify -emit-llvm-only %s -DTEST=3
// expected-no-diagnostics
#include "c.h"
N::A<int> ai;
#if TEST == 1
template<typename> struct A { int n; };
template<typename> struct B { typedef A<void> C; };
@ -11,3 +12,16 @@ template class B<int>;
#include "update.h"
B<int>::C use2;
#elif TEST == 2
#include "c.h"
N::A<int> ai;
#elif TEST == 3
#include "merge.h"
#else
#error Unknown test
#endif