From 3e308b1fbabe8f0d0a0cec1d99d53d4d8f14b316 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Tue, 14 Feb 2012 19:27:52 +0000 Subject: Implement support for lambda capture pack expansions, e.g., [&values...] { print(values...); } llvm-svn: 150497 --- clang/lib/Sema/TreeTransform.h | 51 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 6 deletions(-) (limited to 'clang/lib/Sema/TreeTransform.h') diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index a63b9c804ac..71037b6b3e3 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -7706,6 +7706,49 @@ TreeTransform::TransformLambdaExpr(LambdaExpr *E) { continue; } + // Determine the capture kind for Sema. + Sema::TryCaptureKind Kind + = C->isImplicit()? Sema::TryCapture_Implicit + : C->getCaptureKind() == LCK_ByCopy + ? Sema::TryCapture_ExplicitByVal + : Sema::TryCapture_ExplicitByRef; + SourceLocation EllipsisLoc; + if (C->isPackExpansion()) { + UnexpandedParameterPack Unexpanded(C->getCapturedVar(), C->getLocation()); + bool ShouldExpand = false; + bool RetainExpansion = false; + llvm::Optional NumExpansions; + if (getDerived().TryExpandParameterPacks(C->getEllipsisLoc(), + C->getLocation(), + Unexpanded, + ShouldExpand, RetainExpansion, + NumExpansions)) + return ExprError(); + + if (ShouldExpand) { + // The transform has determined that we should perform an expansion; + // transform and capture each of the arguments. + // expansion of the pattern. Do so. + VarDecl *Pack = C->getCapturedVar(); + for (unsigned I = 0; I != *NumExpansions; ++I) { + Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I); + VarDecl *CapturedVar + = cast_or_null(getDerived().TransformDecl(C->getLocation(), + Pack)); + if (!CapturedVar) { + Invalid = true; + continue; + } + + // Capture the transformed variable. + getSema().TryCaptureVar(CapturedVar, C->getLocation(), Kind); + } + continue; + } + + EllipsisLoc = C->getEllipsisLoc(); + } + // Transform the captured variable. VarDecl *CapturedVar = cast_or_null(getDerived().TransformDecl(C->getLocation(), @@ -7714,13 +7757,9 @@ TreeTransform::TransformLambdaExpr(LambdaExpr *E) { Invalid = true; continue; } - + // Capture the transformed variable. - getSema().TryCaptureVar(CapturedVar, C->getLocation(), - C->isImplicit()? Sema::TryCapture_Implicit - : C->getCaptureKind() == LCK_ByCopy - ? Sema::TryCapture_ExplicitByVal - : Sema::TryCapture_ExplicitByRef); + getSema().TryCaptureVar(CapturedVar, C->getLocation(), Kind); } if (!FinishedExplicitCaptures) getSema().finishLambdaExplicitCaptures(LSI); -- cgit v1.2.3