From: Argyrios Kyrtzidis Date: Fri, 9 Jul 2010 21:11:43 +0000 (+0000) Subject: Reorganize how ClassTemplate[Partial]SpecializationDecls are read/written to avoid the X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ecf966e837097fb2ea0a80391e129bed7361d396;p=clang Reorganize how ClassTemplate[Partial]SpecializationDecls are read/written to avoid the possibility of adding an unitialized one into the folding set. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@108016 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Frontend/PCHReaderDecl.cpp b/lib/Frontend/PCHReaderDecl.cpp index 8b01d3dd1d..dd2d2825f8 100644 --- a/lib/Frontend/PCHReaderDecl.cpp +++ b/lib/Frontend/PCHReaderDecl.cpp @@ -873,36 +873,15 @@ void PCHDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) { if (PrevDecl == 0) { // This ClassTemplateDecl owns a CommonPtr; read it. + // FoldingSets are filled in VisitClassTemplateSpecializationDecl. unsigned size = Record[Idx++]; - while (size--) { - ClassTemplateSpecializationDecl *CTSD - = cast(Reader.GetDecl(Record[Idx++])); - llvm::SmallVector TemplArgs; - Reader.ReadTemplateArgumentList(TemplArgs, Record, Idx); - llvm::FoldingSetNodeID ID; - void *InsertPos = 0; - ClassTemplateSpecializationDecl::Profile(ID, TemplArgs.data(), - TemplArgs.size(), - *Reader.getContext()); - D->getSpecializations().FindNodeOrInsertPos(ID, InsertPos); - D->getSpecializations().InsertNode(CTSD, InsertPos); - } + while (size--) + cast(Reader.GetDecl(Record[Idx++])); size = Record[Idx++]; - while (size--) { - ClassTemplatePartialSpecializationDecl *CTSD - = cast( + while (size--) + cast( Reader.GetDecl(Record[Idx++])); - llvm::SmallVector TemplArgs; - Reader.ReadTemplateArgumentList(TemplArgs, Record, Idx); - llvm::FoldingSetNodeID ID; - void *InsertPos = 0; - ClassTemplatePartialSpecializationDecl::Profile(ID, TemplArgs.data(), - TemplArgs.size(), - *Reader.getContext()); - D->getPartialSpecializations().FindNodeOrInsertPos(ID, InsertPos); - D->getPartialSpecializations().InsertNode(CTSD, InsertPos); - } // InjectedClassNameType is computed. @@ -944,6 +923,21 @@ void PCHDeclReader::VisitClassTemplateSpecializationDecl( if (POI.isValid()) D->setPointOfInstantiation(POI); D->setSpecializationKind((TemplateSpecializationKind)Record[Idx++]); + + if (Record[Idx++]) { // IsKeptInFoldingSet. + ClassTemplateDecl *CanonPattern + = cast(Reader.GetDecl(Record[Idx++])); + if (ClassTemplatePartialSpecializationDecl *Partial + = dyn_cast(D)) { + ClassTemplatePartialSpecializationDecl *Inserted + = CanonPattern->getPartialSpecializations().GetOrInsertNode(Partial); + assert(Inserted == Partial && "Already inserted!"); + } else { + ClassTemplateSpecializationDecl *Inserted + = CanonPattern->getSpecializations().GetOrInsertNode(D); + assert(Inserted == D && "Already inserted!"); + } + } } void PCHDeclReader::VisitClassTemplatePartialSpecializationDecl( diff --git a/lib/Frontend/PCHWriterDecl.cpp b/lib/Frontend/PCHWriterDecl.cpp index 81cb79226b..bc4452ed7f 100644 --- a/lib/Frontend/PCHWriterDecl.cpp +++ b/lib/Frontend/PCHWriterDecl.cpp @@ -233,7 +233,8 @@ void PCHDeclWriter::VisitFunctionDecl(FunctionDecl *D) { case FunctionDecl::TK_FunctionTemplateSpecialization: { FunctionTemplateSpecializationInfo * FTSInfo = D->getTemplateSpecializationInfo(); - Writer.AddDeclRef(FTSInfo->getTemplate(), Record); + // We want it canonical to guarantee that it has a Common*. + Writer.AddDeclRef(FTSInfo->getTemplate()->getCanonicalDecl(), Record); Record.push_back(FTSInfo->getTemplateSpecializationKind()); // Template arguments. @@ -826,6 +827,10 @@ void PCHDeclWriter::VisitTemplateDecl(TemplateDecl *D) { Writer.AddTemplateParameterList(D->getTemplateParameters(), Record); } +static bool IsKeptInFoldingSet(ClassTemplateSpecializationDecl *D) { + return D->getTypeForDecl()->getAsCXXRecordDecl() == D; +} + void PCHDeclWriter::VisitClassTemplateDecl(ClassTemplateDecl *D) { VisitTemplateDecl(D); @@ -833,27 +838,22 @@ void PCHDeclWriter::VisitClassTemplateDecl(ClassTemplateDecl *D) { Writer.AddDeclRef(D->getPreviousDeclaration(), Record); if (D->getPreviousDeclaration() == 0) { // This ClassTemplateDecl owns the CommonPtr; write it. + assert(D->isCanonicalDecl()); typedef llvm::FoldingSet CTSDSetTy; CTSDSetTy &CTSDSet = D->getSpecializations(); Record.push_back(CTSDSet.size()); for (CTSDSetTy::iterator I=CTSDSet.begin(), E = CTSDSet.end(); I!=E; ++I) { - ClassTemplateSpecializationDecl *CTSD = &*I; - Writer.AddDeclRef(CTSD, Record); - // Write the argument list here because we may get it uninitialized when - // reading it back. - Writer.AddTemplateArgumentList(&CTSD->getTemplateArgs(), Record); + assert(IsKeptInFoldingSet(&*I)); + Writer.AddDeclRef(&*I, Record); } typedef llvm::FoldingSet CTPSDSetTy; CTPSDSetTy &CTPSDSet = D->getPartialSpecializations(); Record.push_back(CTPSDSet.size()); for (CTPSDSetTy::iterator I=CTPSDSet.begin(), E=CTPSDSet.end(); I!=E; ++I) { - ClassTemplatePartialSpecializationDecl *CTPSD = &*I; - Writer.AddDeclRef(CTPSD, Record); - // Write the argument list here because we may get it uninitialized when - // reading it back. - Writer.AddTemplateArgumentList(&CTPSD->getTemplateArgs(), Record); + assert(IsKeptInFoldingSet(&*I)); + Writer.AddDeclRef(&*I, Record); } // InjectedClassNameType is computed, no need to write it. @@ -891,6 +891,13 @@ void PCHDeclWriter::VisitClassTemplateSpecializationDecl( Writer.AddSourceLocation(D->getPointOfInstantiation(), Record); Record.push_back(D->getSpecializationKind()); + bool IsInInFoldingSet = IsKeptInFoldingSet(D); + Record.push_back(IsInInFoldingSet); + if (IsInInFoldingSet) { + // When reading, we'll add it to the folding set of this one. + Writer.AddDeclRef(D->getSpecializedTemplate()->getCanonicalDecl(), Record); + } + Code = pch::DECL_CLASS_TEMPLATE_SPECIALIZATION; }