void StmtProfiler::VisitTemplateArgument(const TemplateArgument &Arg) { // Mostly repetitive with TemplateArgument::Profile! ID.AddInteger(Arg.getKind()); switch (Arg.getKind()) { case TemplateArgument::Null: break; case TemplateArgument::Type: VisitType(Arg.getAsType()); break; case TemplateArgument::Template: VisitTemplateName(Arg.getAsTemplate()); break; case TemplateArgument::Declaration: VisitDecl(Arg.getAsDecl()); break; case TemplateArgument::Integral: Arg.getAsIntegral()->Profile(ID); VisitType(Arg.getIntegralType()); break; case TemplateArgument::Expression: Visit(Arg.getAsExpr()); break; case TemplateArgument::Pack: const TemplateArgument *Pack = Arg.pack_begin(); for (unsigned i = 0, e = Arg.pack_size(); i != e; ++i) VisitTemplateArgument(Pack[i]); break; } }
void ODRHash::AddTemplateArgument(TemplateArgument TA) { const auto Kind = TA.getKind(); ID.AddInteger(Kind); switch (Kind) { case TemplateArgument::Null: llvm_unreachable("Expected valid TemplateArgument"); case TemplateArgument::Type: AddQualType(TA.getAsType()); break; case TemplateArgument::Declaration: AddDecl(TA.getAsDecl()); break; case TemplateArgument::NullPtr: case TemplateArgument::Integral: break; case TemplateArgument::Template: case TemplateArgument::TemplateExpansion: AddTemplateName(TA.getAsTemplateOrTemplatePattern()); break; case TemplateArgument::Expression: AddStmt(TA.getAsExpr()); break; case TemplateArgument::Pack: ID.AddInteger(TA.pack_size()); for (auto SubTA : TA.pack_elements()) { AddTemplateArgument(SubTA); } break; } }
SubstNonTypeTemplateParmPackExpr:: SubstNonTypeTemplateParmPackExpr(QualType T, NonTypeTemplateParmDecl *Param, SourceLocation NameLoc, const TemplateArgument &ArgPack) : Expr(SubstNonTypeTemplateParmPackExprClass, T, VK_RValue, OK_Ordinary, true, true, true, true), Param(Param), Arguments(ArgPack.pack_begin()), NumArguments(ArgPack.pack_size()), NameLoc(NameLoc) { }
Optional<unsigned> Sema::getFullyPackExpandedSize(TemplateArgument Arg) { assert(Arg.containsUnexpandedParameterPack()); // If this is a substituted pack, grab that pack. If not, we don't know // the size yet. // FIXME: We could find a size in more cases by looking for a substituted // pack anywhere within this argument, but that's not necessary in the common // case for 'sizeof...(A)' handling. TemplateArgument Pack; switch (Arg.getKind()) { case TemplateArgument::Type: if (auto *Subst = Arg.getAsType()->getAs<SubstTemplateTypeParmPackType>()) Pack = Subst->getArgumentPack(); else return None; break; case TemplateArgument::Expression: if (auto *Subst = dyn_cast<SubstNonTypeTemplateParmPackExpr>(Arg.getAsExpr())) Pack = Subst->getArgumentPack(); else if (auto *Subst = dyn_cast<FunctionParmPackExpr>(Arg.getAsExpr())) { for (ParmVarDecl *PD : *Subst) if (PD->isParameterPack()) return None; return Subst->getNumExpansions(); } else return None; break; case TemplateArgument::Template: if (SubstTemplateTemplateParmPackStorage *Subst = Arg.getAsTemplate().getAsSubstTemplateTemplateParmPack()) Pack = Subst->getArgumentPack(); else return None; break; case TemplateArgument::Declaration: case TemplateArgument::NullPtr: case TemplateArgument::TemplateExpansion: case TemplateArgument::Integral: case TemplateArgument::Pack: case TemplateArgument::Null: return None; } // Check that no argument in the pack is itself a pack expansion. for (TemplateArgument Elem : Pack.pack_elements()) { // There's no point recursing in this case; we would have already // expanded this pack expansion into the enclosing pack if we could. if (Elem.isPackExpansion()) return None; } return Pack.pack_size(); }
void USRGenerator::VisitTemplateArgument(const TemplateArgument &Arg) { switch (Arg.getKind()) { case TemplateArgument::Null: break; case TemplateArgument::Declaration: Visit(Arg.getAsDecl()); break; case TemplateArgument::NullPtr: break; case TemplateArgument::TemplateExpansion: Out << 'P'; // pack expansion of... // Fall through case TemplateArgument::Template: VisitTemplateName(Arg.getAsTemplateOrTemplatePattern()); break; case TemplateArgument::Expression: // FIXME: Visit expressions. break; case TemplateArgument::Pack: Out << 'p' << Arg.pack_size(); for (TemplateArgument::pack_iterator P = Arg.pack_begin(), PEnd = Arg.pack_end(); P != PEnd; ++P) VisitTemplateArgument(*P); break; case TemplateArgument::Type: VisitType(Arg.getAsType()); break; case TemplateArgument::Integral: Out << 'V'; VisitType(Arg.getIntegralType()); Out << Arg.getAsIntegral(); break; } }
void USRGenerator::VisitTemplateArgument(const TemplateArgument &Arg) { switch (Arg.getKind()) { case TemplateArgument::Null: break; case TemplateArgument::Declaration: Visit(Arg.getAsDecl()); break; case TemplateArgument::NullPtr: break; case TemplateArgument::TemplateExpansion: Out << 'P'; // pack expansion of... LLVM_FALLTHROUGH; case TemplateArgument::Template: VisitTemplateName(Arg.getAsTemplateOrTemplatePattern()); break; case TemplateArgument::Expression: // FIXME: Visit expressions. break; case TemplateArgument::Pack: Out << 'p' << Arg.pack_size(); for (const auto &P : Arg.pack_elements()) VisitTemplateArgument(P); break; case TemplateArgument::Type: VisitType(Arg.getAsType()); break; case TemplateArgument::Integral: Out << 'V'; VisitType(Arg.getIntegralType()); Out << Arg.getAsIntegral(); break; } }