From 7b3b95a9485059b196896accc0144fd0bc31ff2c Mon Sep 17 00:00:00 2001 From: Axel Naumann Date: Mon, 1 Oct 2012 07:34:47 +0000 Subject: [PATCH] Bring ASTReader and Writer into sync for the case where a canonical template specialization was written, which is non-canonical at the time of reading: force the reading of the ClassTemplateDecl if it was written. The easiest way out is to store whether the decl was canonical at the time of writing. Add test. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@164927 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Serialization/ASTReaderDecl.cpp | 17 ++++++++++------- lib/Serialization/ASTWriterDecl.cpp | 1 + test/Modules/Inputs/redecl-merge-left.h | 6 ++++++ test/Modules/Inputs/redecl-merge-right.h | 6 ++++++ test/Modules/Inputs/redecl-merge-top.h | 5 +++++ test/Modules/redecl-merge.m | 3 +++ 6 files changed, 31 insertions(+), 7 deletions(-) diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp index c9788a3216..843893d90f 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/lib/Serialization/ASTReaderDecl.cpp @@ -1395,14 +1395,17 @@ void ASTDeclReader::VisitClassTemplateSpecializationDecl( TemplArgs.size()); D->PointOfInstantiation = ReadSourceLocation(Record, Idx); D->SpecializationKind = (TemplateSpecializationKind)Record[Idx++]; - - if (D->isCanonicalDecl()) { // It's kept in the folding set. + + bool writtenAsCanonicalDecl = Record[Idx++]; + if (writtenAsCanonicalDecl) { ClassTemplateDecl *CanonPattern = ReadDeclAs(Record,Idx); - if (ClassTemplatePartialSpecializationDecl *Partial - = dyn_cast(D)) { - CanonPattern->getCommonPtr()->PartialSpecializations.InsertNode(Partial); - } else { - CanonPattern->getCommonPtr()->Specializations.InsertNode(D); + if (D->isCanonicalDecl()) { // It's kept in the folding set. + if (ClassTemplatePartialSpecializationDecl *Partial + = dyn_cast(D)) { + CanonPattern->getCommonPtr()->PartialSpecializations.InsertNode(Partial); + } else { + CanonPattern->getCommonPtr()->Specializations.InsertNode(D); + } } } } diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp index 7122bca969..0f9bb3824b 100644 --- a/lib/Serialization/ASTWriterDecl.cpp +++ b/lib/Serialization/ASTWriterDecl.cpp @@ -1106,6 +1106,7 @@ void ASTDeclWriter::VisitClassTemplateSpecializationDecl( Writer.AddTemplateArgumentList(&D->getTemplateArgs(), Record); Writer.AddSourceLocation(D->getPointOfInstantiation(), Record); Record.push_back(D->getSpecializationKind()); + Record.push_back(D->isCanonicalDecl()); if (D->isCanonicalDecl()) { // When reading, we'll add it to the folding set of the following template. diff --git a/test/Modules/Inputs/redecl-merge-left.h b/test/Modules/Inputs/redecl-merge-left.h index b3a7ba83c1..4bdd01570f 100644 --- a/test/Modules/Inputs/redecl-merge-left.h +++ b/test/Modules/Inputs/redecl-merge-left.h @@ -82,6 +82,12 @@ extern double var3; template class Vector; template class Vector; + +template class List; +template<> class List { +public: + void push_back(int); +}; #endif // Make sure this doesn't introduce an ambiguity-creating 'id' at the diff --git a/test/Modules/Inputs/redecl-merge-right.h b/test/Modules/Inputs/redecl-merge-right.h index de7aa08cfb..695327674f 100644 --- a/test/Modules/Inputs/redecl-merge-right.h +++ b/test/Modules/Inputs/redecl-merge-right.h @@ -83,6 +83,12 @@ template class Vector { public: void push_back(const T&); }; + +template class List; +template<> class List { +public: + void push_back(int); +}; #endif int ONE; diff --git a/test/Modules/Inputs/redecl-merge-top.h b/test/Modules/Inputs/redecl-merge-top.h index 519254ca22..7053936b2c 100644 --- a/test/Modules/Inputs/redecl-merge-top.h +++ b/test/Modules/Inputs/redecl-merge-top.h @@ -17,4 +17,9 @@ struct S2; #ifdef __cplusplus template class Vector; + +template class List { +public: + void push_back(T); +}; #endif diff --git a/test/Modules/redecl-merge.m b/test/Modules/redecl-merge.m index d7930aca2e..0e5cd4ac37 100644 --- a/test/Modules/redecl-merge.m +++ b/test/Modules/redecl-merge.m @@ -150,6 +150,9 @@ id p3; void testVector() { Vector vec_int; vec_int.push_back(0); + + List list_bool; + list_bool.push_back(false); } #endif -- 2.40.0