diff options
Diffstat (limited to 'clang/lib/Sema/TreeTransform.h')
-rw-r--r-- | clang/lib/Sema/TreeTransform.h | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index a74171ed5f8..6aa1dbbc442 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -10763,6 +10763,51 @@ TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) { E->getRParenLoc(), None, None); } + // Try to compute the result without performing a partial substitution. + Optional<unsigned> Result = 0; + for (const TemplateArgument &Arg : PackArgs) { + if (!Arg.isPackExpansion()) { + Result = *Result + 1; + continue; + } + + TemplateArgumentLoc ArgLoc; + InventTemplateArgumentLoc(Arg, ArgLoc); + + // Find the pattern of the pack expansion. + SourceLocation Ellipsis; + Optional<unsigned> OrigNumExpansions; + TemplateArgumentLoc Pattern = + getSema().getTemplateArgumentPackExpansionPattern(ArgLoc, Ellipsis, + OrigNumExpansions); + + // Substitute under the pack expansion. Do not expand the pack (yet). + TemplateArgumentLoc OutPattern; + Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1); + if (getDerived().TransformTemplateArgument(Pattern, OutPattern, + /*Uneval*/ true)) + return true; + + // See if we can determine the number of arguments from the result. + Optional<unsigned> NumExpansions = + getSema().getFullyPackExpandedSize(OutPattern.getArgument()); + if (!NumExpansions) { + // No: we must be in an alias template expansion, and we're going to need + // to actually expand the packs. + Result = None; + break; + } + + Result = *Result + *NumExpansions; + } + + // Common case: we could determine the number of expansions without + // substituting. + if (Result) + return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), E->getPack(), + E->getPackLoc(), + E->getRParenLoc(), *Result, None); + TemplateArgumentListInfo TransformedPackArgs(E->getPackLoc(), E->getPackLoc()); { @@ -10775,6 +10820,8 @@ TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) { return ExprError(); } + // Check whether we managed to fully-expand the pack. + // FIXME: Is it possible for us to do so and not hit the early exit path? SmallVector<TemplateArgument, 8> Args; bool PartialSubstitution = false; for (auto &Loc : TransformedPackArgs.arguments()) { |