void InstantiateTemplateParam::handleOneTemplateSpecialization( const TemplateDecl *D, const TemplateArgumentList & ArgList) { if (isInIncludedFile(D)) return; NamedDecl *ND = D->getTemplatedDecl(); TemplateParameterSet ParamsSet; TemplateParameterVisitor ParameterVisitor(ParamsSet); ParameterVisitor.TraverseDecl(ND); if (ParamsSet.size() == 0) return; unsigned NumArgs = ArgList.size(); (void)NumArgs; unsigned Idx = 0; TemplateParameterList *TPList = D->getTemplateParameters(); for (TemplateParameterList::const_iterator I = TPList->begin(), E = TPList->end(); I != E; ++I) { const NamedDecl *ND = (*I); // make it simple, skip NonTypeTemplateParmDecl and // TemplateTemplateParmDecl for now const TemplateTypeParmDecl *TyParmDecl = dyn_cast<TemplateTypeParmDecl>(ND); if (!TyParmDecl || TyParmDecl->isParameterPack() || !ParamsSet.count(ND)) { Idx++; continue; } TransAssert((Idx < NumArgs) && "Invalid Idx!"); const TemplateArgument &Arg = ArgList.get(Idx); std::string ArgStr; std::string ForwardStr; if (!getTemplateArgumentString(Arg, ArgStr, ForwardStr)) continue; ValidInstanceNum++; if (ValidInstanceNum == TransformationCounter) { TheInstantiationString = ArgStr; TheParameter = ND; TheTemplateDecl = D; TheForwardDeclString = ForwardStr; } } }
void TemplateArgToInt::collectInvalidParamIdx( const TemplateDecl *D, TemplateParameterIdxSet &InvalidParamIdx) { TemplateParameterSet InvalidParams; NamedDecl *ND = D->getTemplatedDecl(); TemplateInvalidParameterVisitor ParameterVisitor(InvalidParams, this); ParameterVisitor.TraverseDecl(ND); TemplateParameterList *TPList = D->getTemplateParameters(); unsigned Idx = 0; for (TemplateParameterList::const_iterator I = TPList->begin(), E = TPList->end(); I != E; ++I) { const NamedDecl *ParamND = (*I); ParamToTemplateDecl[ParamND] = D; if (InvalidParams.count(ParamND)) { TransAssert(!InvalidParamIdx.count(Idx) && "Duplicate Index!"); InvalidParamIdx.insert(Idx); } Idx++; } }
bool ReduceClassTemplateParameterASTVisitor::VisitClassTemplateDecl( ClassTemplateDecl *D) { if (ConsumerInstance->isInIncludedFile(D)) return true; ClassTemplateDecl *CanonicalD = D->getCanonicalDecl(); if (ConsumerInstance->VisitedDecls.count(CanonicalD)) return true; ConsumerInstance->VisitedDecls.insert(CanonicalD); if (!ConsumerInstance->isValidClassTemplateDecl(D)) return true; TemplateParameterSet ParamsSet; TemplateParameterVisitor ParameterVisitor(ParamsSet); CXXRecordDecl *CXXRD = D->getTemplatedDecl(); CXXRecordDecl *Def = CXXRD->getDefinition(); if (Def) ParameterVisitor.TraverseDecl(Def); // ISSUE: we should also check the parameter usage for partial template // specializations. For example: // template<typename T1, typename T2> struct S{}; // template<typename T1, typename T2> struct<T1 *, T2 *> S{...}; // T1 or T2 could be used in "..." // Also, we could have another bad transformation, for example, // template<bool, typename T> struct S{}; // template<typename T> struct<true, T> S{}; // if we remove bool and true, we will have two definitions for S TemplateParameterList *TPList; if (Def) { // make sure we use the params as in ParameterVisitor const ClassTemplateDecl *CT = Def->getDescribedClassTemplate(); TransAssert(CT && "NULL DescribedClassTemplate!"); TPList = CT->getTemplateParameters(); } else { TPList = CanonicalD->getTemplateParameters(); } unsigned Index = 0; for (TemplateParameterList::const_iterator I = TPList->begin(), E = TPList->end(); I != E; ++I) { const NamedDecl *ND = (*I); if (ParamsSet.count(ND)) { Index++; continue; } ConsumerInstance->ValidInstanceNum++; if (ConsumerInstance->ValidInstanceNum == ConsumerInstance->TransformationCounter) { ConsumerInstance->TheClassTemplateDecl = CanonicalD; ConsumerInstance->TheParameterIndex = Index; ConsumerInstance->TheTemplateName = new TemplateName(CanonicalD); ConsumerInstance->setDefaultArgFlag(ND); } Index++; } return true; }