bool ClassTemplateToClassSpecializationTypeRewriteVisitor:: VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc Loc) { const TemplateSpecializationType *Ty = dyn_cast<TemplateSpecializationType>(Loc.getTypePtr()); TransAssert(Ty && "Invalid TemplateSpecializationType!"); TemplateName TmplName = Ty->getTemplateName(); if (!ConsumerInstance->referToTheTemplateDecl(TmplName)) return true; SourceLocation TmplKeyLoc = Loc.getTemplateKeywordLoc(); if (TmplKeyLoc.isValid()) ConsumerInstance->TheRewriter.RemoveText(TmplKeyLoc, 8); // it's necessary to check the validity of locations, otherwise // we will get assertion errors... // note that some implicit typeloc has been visited by Clang, e.g. // template < typename > struct A { }; // struct B:A < int > { // B ( ) { } // }; // base initializer A<int> is not presented in the code but visited, // so, we need to make sure locations are valid. SourceLocation LAngleLoc = Loc.getLAngleLoc(); if (LAngleLoc.isInvalid()) return true; SourceLocation RAngleLoc = Loc.getRAngleLoc(); if (RAngleLoc.isInvalid()) return true; ConsumerInstance->TheRewriter.RemoveText(SourceRange(LAngleLoc, RAngleLoc)); return true; }
bool UnnecessaryIncludeFinder::VisitTemplateSpecializationTypeLoc ( TemplateSpecializationTypeLoc typeLoc) { CXXRecordDecl* pCXXRecordDecl = typeLoc.getTypePtr()->getAsCXXRecordDecl(); if (pCXXRecordDecl) { markUsed(pCXXRecordDecl->getLocation(), typeLoc.getTemplateNameLoc()); } return true; }
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)); } }
bool ClassTemplateToClassSpecializationTypeRewriteVisitor:: VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc Loc) { const TemplateSpecializationType *Ty = dyn_cast<TemplateSpecializationType>(Loc.getTypePtr()); TransAssert(Ty && "Invalid TemplateSpecializationType!"); TemplateName TmplName = Ty->getTemplateName(); if (!ConsumerInstance->referToTheTemplateDecl(TmplName)) return true; SourceLocation TmplKeyLoc = Loc.getTemplateKeywordLoc(); if (TmplKeyLoc.isValid()) ConsumerInstance->TheRewriter.RemoveText(TmplKeyLoc, 8); ConsumerInstance->TheRewriter.RemoveText(SourceRange(Loc.getLAngleLoc(), Loc.getRAngleLoc())); return true; }
bool RemoveNamespaceRewriteVisitor::VisitTemplateSpecializationTypeLoc( TemplateSpecializationTypeLoc TSPLoc) { const Type *Ty = TSPLoc.getTypePtr(); const TemplateSpecializationType *TST = dyn_cast<TemplateSpecializationType>(Ty); TransAssert(TST && "Bad TemplateSpecializationType!"); TemplateName TplName = TST->getTemplateName(); const TemplateDecl *TplD = TplName.getAsTemplateDecl(); TransAssert(TplD && "Invalid TemplateDecl!"); NamedDecl *ND = TplD->getTemplatedDecl(); // in some cases, ND could be NULL, e.g., the // template template parameter code below: // template<template<class> class BBB> // struct AAA { // template <class T> // struct CCC { // static BBB<T> a; // }; // }; // where we don't know BBB if (!ND) return true; const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(ND); if (!CXXRD) return true; std::string Name; if (ConsumerInstance->getNewName(CXXRD, Name)) { SourceLocation LocStart = TSPLoc.getTemplateNameLoc(); ConsumerInstance->TheRewriter.ReplaceText( LocStart, CXXRD->getNameAsString().size(), Name); } return true; }