void printTemplateName(raw_ostream &OS, const PrintingPolicy &policy, TemplateName const &name, bool qualifyNames = false) { if (auto Template = name.getAsTemplateDecl()) OS << (qualifyNames ? Template->getQualifiedNameAsString() : Template->getNameAsString()); else if (auto QTN = name.getAsQualifiedTemplateName()) { OS << (qualifyNames ? QTN->getDecl()->getQualifiedNameAsString() : QTN->getDecl()->getNameAsString()); } else if (auto DTN = name.getAsDependentTemplateName()) { if (qualifyNames && DTN->getQualifier()) DTN->getQualifier()->print(OS, policy); OS << "template "; if (DTN->isIdentifier()) OS << DTN->getIdentifier()->getName(); else OS << "operator " << getOperatorSpelling(DTN->getOperator()); } else if (auto subst = name.getAsSubstTemplateTemplateParm()) { subst->getReplacement().print(OS, policy, !qualifyNames); } else if (auto SubstPack = name.getAsSubstTemplateTemplateParmPack()) OS << *SubstPack->getParameterPack(); else { auto OTS = name.getAsOverloadedTemplate(); (*OTS->begin())->printName(OS); } }
static bool getFullyQualifiedTemplateName(const ASTContext &Ctx, TemplateName &TName) { bool Changed = false; NestedNameSpecifier *NNS = nullptr; TemplateDecl *ArgTDecl = TName.getAsTemplateDecl(); // ArgTDecl won't be NULL because we asserted that this isn't a // dependent context very early in the call chain. assert(ArgTDecl != nullptr); QualifiedTemplateName *QTName = TName.getAsQualifiedTemplateName(); if (QTName && !QTName->hasTemplateKeyword()) { NNS = QTName->getQualifier(); NestedNameSpecifier *QNNS = getFullyQualifiedNestedNameSpecifier(Ctx, NNS); if (QNNS != NNS) { Changed = true; NNS = QNNS; } else { NNS = nullptr; } } else { NNS = createNestedNameSpecifierForScopeOf(Ctx, ArgTDecl, true); } if (NNS) { TName = Ctx.getQualifiedTemplateName(NNS, /*TemplateKeyword=*/false, ArgTDecl); Changed = true; } return Changed; }
void TemplateSpecializationTypeLoc::initializeArgLocs(ASTContext &Context, unsigned NumArgs, const TemplateArgument *Args, TemplateArgumentLocInfo *ArgInfos, SourceLocation Loc) { for (unsigned i = 0, e = NumArgs; i != e; ++i) { switch (Args[i].getKind()) { case TemplateArgument::Null: llvm_unreachable("Impossible TemplateArgument"); case TemplateArgument::Integral: case TemplateArgument::Declaration: case TemplateArgument::NullPtr: ArgInfos[i] = TemplateArgumentLocInfo(); break; case TemplateArgument::Expression: ArgInfos[i] = TemplateArgumentLocInfo(Args[i].getAsExpr()); break; case TemplateArgument::Type: ArgInfos[i] = TemplateArgumentLocInfo( Context.getTrivialTypeSourceInfo(Args[i].getAsType(), Loc)); break; case TemplateArgument::Template: case TemplateArgument::TemplateExpansion: { NestedNameSpecifierLocBuilder Builder; TemplateName Template = Args[i].getAsTemplateOrTemplatePattern(); if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) Builder.MakeTrivial(Context, DTN->getQualifier(), Loc); else if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName()) Builder.MakeTrivial(Context, QTN->getQualifier(), Loc); ArgInfos[i] = TemplateArgumentLocInfo( Builder.getWithLocInContext(Context), Loc, Args[i].getKind() == TemplateArgument::Template ? SourceLocation() : Loc); break; } case TemplateArgument::Pack: ArgInfos[i] = TemplateArgumentLocInfo(); break; } } }