bool ReduceClassTemplateParameterRewriteVisitor:: VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc Loc) { // Invalidation can be introduced by constructor's initialization list, e.g.: // template<typename T1, typename T2> class A { }; // class B : public A<int, int> { // int m; // B(int x) : m(x) {} // }; // In RecursiveASTVisitor.h, TraverseConstructorInitializer will visit the part // of initializing base class's, i.e. through base's default constructor if (Loc.getBeginLoc().isInvalid()) return true; const TemplateSpecializationType *Ty = dyn_cast<TemplateSpecializationType>(Loc.getTypePtr()); TransAssert(Ty && "Invalid TemplateSpecializationType!"); TemplateName TmplName = Ty->getTemplateName(); if (!ConsumerInstance->referToTheTemplateDecl(TmplName)) return true; unsigned NumArgs = Loc.getNumArgs(); // I would put a stronger assert here, i.e., // " (ConsumerInstance->TheParameterIndex >= NumArgs) && // ConsumerInstance->hasDefaultArg " // but sometimes ill-formed input could yield incomplete // info, e.g., for two template decls which refer to the same // template def, one decl could have a non-null default arg, // while another decl's default arg field could be null. if (ConsumerInstance->TheParameterIndex >= NumArgs) return true; TransAssert((ConsumerInstance->TheParameterIndex < NumArgs) && "TheParameterIndex cannot be greater than NumArgs!"); TemplateArgumentLoc ArgLoc = Loc.getArgLoc(ConsumerInstance->TheParameterIndex); SourceRange Range = ArgLoc.getSourceRange(); if (NumArgs == 1) { ConsumerInstance->TheRewriter.ReplaceText(SourceRange(Loc.getLAngleLoc(), Loc.getRAngleLoc()), "<>"); } else if ((ConsumerInstance->TheParameterIndex + 1) == NumArgs) { SourceLocation EndLoc = Loc.getRAngleLoc(); EndLoc = EndLoc.getLocWithOffset(-1); ConsumerInstance->RewriteHelper->removeTextFromLeftAt( Range, ',', EndLoc); } else { ConsumerInstance->RewriteHelper->removeTextUntil(Range, ','); } return true; }
void TemplateArgToInt::handleTemplateSpecializationTypeLoc( const TemplateSpecializationTypeLoc &TLoc) { const Type *Ty = TLoc.getTypePtr(); const TemplateSpecializationType *TST = Ty->getAs<TemplateSpecializationType>(); TemplateName TplName = TST->getTemplateName(); const TemplateDecl *TplD = TplName.getAsTemplateDecl(); TemplateParameterIdxSet *InvalidIdx = DeclToParamIdx[dyn_cast<TemplateDecl>(TplD->getCanonicalDecl())]; if (!InvalidIdx) return; for (unsigned I = 0; I < TLoc.getNumArgs(); ++I) { if (!InvalidIdx->count(I)) handleOneTemplateArgumentLoc(TLoc.getArgLoc(I)); } }