From 393f4e7615b1f08b4cb878f318a0da7bf5b639ca Mon Sep 17 00:00:00 2001 From: Vassil Vassilev <vvasilev@cern.ch> Date: Tue, 10 Dec 2013 10:52:00 +0100 Subject: [PATCH] Remove 'properly' the function template specializations. --- .../cling/lib/Interpreter/ASTNodeEraser.cpp | 49 +++++++++++++------ 1 file changed, 33 insertions(+), 16 deletions(-) diff --git a/interpreter/cling/lib/Interpreter/ASTNodeEraser.cpp b/interpreter/cling/lib/Interpreter/ASTNodeEraser.cpp index 312b84146cc..4212d52007d 100644 --- a/interpreter/cling/lib/Interpreter/ASTNodeEraser.cpp +++ b/interpreter/cling/lib/Interpreter/ASTNodeEraser.cpp @@ -435,25 +435,43 @@ namespace cling { class FunctionTemplateDeclExt : public FunctionTemplateDecl { public: static void removeSpecialization(FunctionTemplateDecl* self, - const FunctionTemplateSpecializationInfo* info) { - assert(self && "Cannot be null!"); - typedef llvm::SmallVector<FunctionTemplateSpecializationInfo*,4> Vector; + const FunctionDecl* specialization) { + assert(self && specialization && "Cannot be null!"); + typedef llvm::SmallVector<FunctionDecl*, 4> Specializations; typedef llvm::FoldingSetVector< FunctionTemplateSpecializationInfo> Set; + FunctionTemplateDeclExt* This = (FunctionTemplateDeclExt*) self; - Vector specInfos; - Set specs = This->getSpecializations(); - // Copy the addresses and then cleanup the list of specializations. - for(Set::iterator I = specs.begin(), E = specs.end(); I != E; ++I) - specInfos.push_back(&*I); + Specializations specializations; + const Set& specs = This->getSpecializations(); + + if (!specs.size()) // nothing to remove + return; + + // Collect all the specializations without the one to remove. + for(Set::const_iterator I = specs.begin(),E = specs.end(); I != E; ++I){ + assert(I->Function && "Must have a specialization."); + if (I->Function != specialization) + specializations.push_back(I->Function); + } + This->getSpecializations().clear(); - //Append the new list of specializations. + //Readd the collected specializations. void* InsertPos = 0; - for (size_t i = 0, e = specInfos.size(); i < e; ++i) - if (specInfos[i] != info) { - specInfos[i]->SetNextInBucket(0); // reset the next in bucket. - This->addSpecialization(specInfos[i], InsertPos); - } + FunctionTemplateSpecializationInfo* FTSI = 0; + for (size_t i = 0, e = specializations.size(); i < e; ++i) { + FTSI = specializations[i]->getTemplateSpecializationInfo(); + assert(FTSI && "Must not be null."); + // Avoid assertion on add. + FTSI->SetNextInBucket(0); + This->addSpecialization(FTSI, InsertPos); + } +#ifndef NDEBUG + const TemplateArgumentList* args + = specialization->getTemplateSpecializationArgs(); + assert(!self->findSpecialization(args->data(), args->size(), InsertPos) + && "Finds the removed decl again!"); +#endif } }; @@ -464,8 +482,7 @@ namespace cling { FunctionDecl* CanFD = FD->getCanonicalDecl(); FunctionTemplateDecl* FTD = FD->getTemplateSpecializationInfo()->getTemplate(); - FunctionTemplateDeclExt::removeSpecialization(FTD, - CanFD->getTemplateSpecializationInfo()); + FunctionTemplateDeclExt::removeSpecialization(FTD, CanFD); } return Successful; -- GitLab