diff options
author | Axel Naumann <Axel.Naumann@cern.ch> | 2012-10-01 07:34:47 +0000 |
---|---|---|
committer | Axel Naumann <Axel.Naumann@cern.ch> | 2012-10-01 07:34:47 +0000 |
commit | a31dee2e04da90852e03628ca80949b992d4eabd (patch) | |
tree | dc205f185026c7adf96a3247b1edac1223ffd242 | |
parent | 4ca8ca916ea5bb3335081ffa099bcdf2db13f080 (diff) | |
download | bcm5719-llvm-a31dee2e04da90852e03628ca80949b992d4eabd.tar.gz bcm5719-llvm-a31dee2e04da90852e03628ca80949b992d4eabd.zip |
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.
llvm-svn: 164927
-rw-r--r-- | clang/lib/Serialization/ASTReaderDecl.cpp | 17 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriterDecl.cpp | 1 | ||||
-rw-r--r-- | clang/test/Modules/Inputs/redecl-merge-left.h | 6 | ||||
-rw-r--r-- | clang/test/Modules/Inputs/redecl-merge-right.h | 6 | ||||
-rw-r--r-- | clang/test/Modules/Inputs/redecl-merge-top.h | 5 | ||||
-rw-r--r-- | clang/test/Modules/redecl-merge.m | 3 |
6 files changed, 31 insertions, 7 deletions
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index c9788a32164..843893d90f2 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/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<ClassTemplateDecl>(Record,Idx); - if (ClassTemplatePartialSpecializationDecl *Partial - = dyn_cast<ClassTemplatePartialSpecializationDecl>(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<ClassTemplatePartialSpecializationDecl>(D)) { + CanonPattern->getCommonPtr()->PartialSpecializations.InsertNode(Partial); + } else { + CanonPattern->getCommonPtr()->Specializations.InsertNode(D); + } } } } diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index 7122bca9699..0f9bb3824b8 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/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/clang/test/Modules/Inputs/redecl-merge-left.h b/clang/test/Modules/Inputs/redecl-merge-left.h index b3a7ba83c1a..4bdd01570f6 100644 --- a/clang/test/Modules/Inputs/redecl-merge-left.h +++ b/clang/test/Modules/Inputs/redecl-merge-left.h @@ -82,6 +82,12 @@ extern double var3; template<typename T> class Vector; template<typename T> class Vector; + +template<typename T> class List; +template<> class List<bool> { +public: + void push_back(int); +}; #endif // Make sure this doesn't introduce an ambiguity-creating 'id' at the diff --git a/clang/test/Modules/Inputs/redecl-merge-right.h b/clang/test/Modules/Inputs/redecl-merge-right.h index de7aa08cfb2..695327674fb 100644 --- a/clang/test/Modules/Inputs/redecl-merge-right.h +++ b/clang/test/Modules/Inputs/redecl-merge-right.h @@ -83,6 +83,12 @@ template<typename T> class Vector { public: void push_back(const T&); }; + +template<typename T> class List; +template<> class List<bool> { +public: + void push_back(int); +}; #endif int ONE; diff --git a/clang/test/Modules/Inputs/redecl-merge-top.h b/clang/test/Modules/Inputs/redecl-merge-top.h index 519254ca221..7053936b2cc 100644 --- a/clang/test/Modules/Inputs/redecl-merge-top.h +++ b/clang/test/Modules/Inputs/redecl-merge-top.h @@ -17,4 +17,9 @@ struct S2; #ifdef __cplusplus template<typename T> class Vector; + +template<typename T> class List { +public: + void push_back(T); +}; #endif diff --git a/clang/test/Modules/redecl-merge.m b/clang/test/Modules/redecl-merge.m index d7930aca2ec..0e5cd4ac37d 100644 --- a/clang/test/Modules/redecl-merge.m +++ b/clang/test/Modules/redecl-merge.m @@ -150,6 +150,9 @@ id<P3> p3; void testVector() { Vector<int> vec_int; vec_int.push_back(0); + + List<bool> list_bool; + list_bool.push_back(false); } #endif |