aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaLambda.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2012-07-25 03:56:55 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2012-07-25 03:56:55 +0000
commit612409ece080e814f79e06772c690d603f45fbd6 (patch)
tree537d937d27dae8aec0b0bdf586cd8f2dfaaa9d59 /lib/Sema/SemaLambda.cpp
parent6f36366c85dc81d67d70efdeeea4cfc382053feb (diff)
PR12057: Allow variadic template pack expansions to cross lambda boundaries.
Rather than adding a ContainsUnexpandedParameterPack bit to essentially every AST node, we tunnel the bit directly up to the surrounding lambda expression when we reach a context where an unexpanded pack can not normally appear. Thus any statement or declaration within a lambda can now potentially contain an unexpanded parameter pack. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@160705 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaLambda.cpp')
-rw-r--r--lib/Sema/SemaLambda.cpp28
1 files changed, 10 insertions, 18 deletions
diff --git a/lib/Sema/SemaLambda.cpp b/lib/Sema/SemaLambda.cpp
index 25d27f44ee..3a10c2af91 100644
--- a/lib/Sema/SemaLambda.cpp
+++ b/lib/Sema/SemaLambda.cpp
@@ -375,6 +375,7 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
TypeSourceInfo *MethodTyInfo;
bool ExplicitParams = true;
bool ExplicitResultType = true;
+ bool ContainsUnexpandedParameterPack = false;
SourceLocation EndLoc;
llvm::ArrayRef<ParmVarDecl *> Params;
if (ParamInfo.getNumTypeObjects() == 0) {
@@ -416,21 +417,8 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
Proto.getNumArgs());
// Check for unexpanded parameter packs in the method type.
- // FIXME: We should allow unexpanded parameter packs here, but that would,
- // in turn, make the lambda expression contain unexpanded parameter packs.
- if (DiagnoseUnexpandedParameterPack(Intro.Range.getBegin(), MethodTyInfo,
- UPPC_Lambda)) {
- // Drop the parameters.
- Params = llvm::ArrayRef<ParmVarDecl *>();
- FunctionProtoType::ExtProtoInfo EPI;
- EPI.HasTrailingReturn = false;
- EPI.TypeQuals |= DeclSpec::TQ_const;
- QualType MethodTy = Context.getFunctionType(Context.DependentTy,
- /*Args=*/0, /*NumArgs=*/0, EPI);
- MethodTyInfo = Context.getTrivialTypeSourceInfo(MethodTy);
- ExplicitParams = false;
- ExplicitResultType = false;
- }
+ if (MethodTyInfo->getType()->containsUnexpandedParameterPack())
+ ContainsUnexpandedParameterPack = true;
}
CXXMethodDecl *Method = startLambdaDefinition(Class, Intro.Range,
@@ -571,8 +559,7 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
// Just ignore the ellipsis.
}
} else if (Var->isParameterPack()) {
- Diag(C->Loc, diag::err_lambda_unexpanded_pack);
- continue;
+ ContainsUnexpandedParameterPack = true;
}
TryCaptureKind Kind = C->Kind == LCK_ByRef ? TryCapture_ExplicitByRef :
@@ -581,6 +568,8 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
}
finishLambdaExplicitCaptures(LSI);
+ LSI->ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack;
+
// Add lambda parameters into scope.
addLambdaParameters(Method, CurScope);
@@ -743,6 +732,7 @@ ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body,
bool ExplicitParams;
bool ExplicitResultType;
bool LambdaExprNeedsCleanups;
+ bool ContainsUnexpandedParameterPack;
llvm::SmallVector<VarDecl *, 4> ArrayIndexVars;
llvm::SmallVector<unsigned, 4> ArrayIndexStarts;
{
@@ -753,6 +743,7 @@ ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body,
ExplicitParams = LSI->ExplicitParams;
ExplicitResultType = !LSI->HasImplicitReturnType;
LambdaExprNeedsCleanups = LSI->ExprNeedsCleanups;
+ ContainsUnexpandedParameterPack = LSI->ContainsUnexpandedParameterPack;
ArrayIndexVars.swap(LSI->ArrayIndexVars);
ArrayIndexStarts.swap(LSI->ArrayIndexStarts);
@@ -867,7 +858,8 @@ ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body,
CaptureDefault, Captures,
ExplicitParams, ExplicitResultType,
CaptureInits, ArrayIndexVars,
- ArrayIndexStarts, Body->getLocEnd());
+ ArrayIndexStarts, Body->getLocEnd(),
+ ContainsUnexpandedParameterPack);
// C++11 [expr.prim.lambda]p2:
// A lambda-expression shall not appear in an unevaluated operand