TemplateArgumentLoc Sema::getTemplateArgumentPackExpansionPattern( TemplateArgumentLoc OrigLoc, SourceLocation &Ellipsis, Optional<unsigned> &NumExpansions) const { const TemplateArgument &Argument = OrigLoc.getArgument(); assert(Argument.isPackExpansion()); switch (Argument.getKind()) { case TemplateArgument::Type: { // FIXME: We shouldn't ever have to worry about missing // type-source info! TypeSourceInfo *ExpansionTSInfo = OrigLoc.getTypeSourceInfo(); if (!ExpansionTSInfo) ExpansionTSInfo = Context.getTrivialTypeSourceInfo(Argument.getAsType(), Ellipsis); PackExpansionTypeLoc Expansion = ExpansionTSInfo->getTypeLoc().castAs<PackExpansionTypeLoc>(); Ellipsis = Expansion.getEllipsisLoc(); TypeLoc Pattern = Expansion.getPatternLoc(); NumExpansions = Expansion.getTypePtr()->getNumExpansions(); // We need to copy the TypeLoc because TemplateArgumentLocs store a // TypeSourceInfo. // FIXME: Find some way to avoid the copy? TypeLocBuilder TLB; TLB.pushFullCopy(Pattern); TypeSourceInfo *PatternTSInfo = TLB.getTypeSourceInfo(Context, Pattern.getType()); return TemplateArgumentLoc(TemplateArgument(Pattern.getType()), PatternTSInfo); } case TemplateArgument::Expression: { PackExpansionExpr *Expansion = cast<PackExpansionExpr>(Argument.getAsExpr()); Expr *Pattern = Expansion->getPattern(); Ellipsis = Expansion->getEllipsisLoc(); NumExpansions = Expansion->getNumExpansions(); return TemplateArgumentLoc(Pattern, Pattern); } case TemplateArgument::TemplateExpansion: Ellipsis = OrigLoc.getTemplateEllipsisLoc(); NumExpansions = Argument.getNumTemplateExpansions(); return TemplateArgumentLoc(Argument.getPackExpansionPattern(), OrigLoc.getTemplateQualifierLoc(), OrigLoc.getTemplateNameLoc()); case TemplateArgument::Declaration: case TemplateArgument::NullPtr: case TemplateArgument::Template: case TemplateArgument::Integral: case TemplateArgument::Pack: case TemplateArgument::Null: return TemplateArgumentLoc(); } llvm_unreachable("Invalid TemplateArgument Kind!"); }
TypeSourceInfo * Sema::CheckPackExpansion(TypeSourceInfo *Pattern, SourceLocation EllipsisLoc, Optional<unsigned> NumExpansions) { // Create the pack expansion type and source-location information. QualType Result = CheckPackExpansion(Pattern->getType(), Pattern->getTypeLoc().getSourceRange(), EllipsisLoc, NumExpansions); if (Result.isNull()) return nullptr; TypeLocBuilder TLB; TLB.pushFullCopy(Pattern->getTypeLoc()); PackExpansionTypeLoc TL = TLB.push<PackExpansionTypeLoc>(Result); TL.setEllipsisLoc(EllipsisLoc); return TLB.getTypeSourceInfo(Context, Result); }