diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-07-25 03:56:55 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-07-25 03:56:55 +0000 |
commit | 2589b9808e2a08ee51b2b0e03164303d2b74c6ed (patch) | |
tree | d28722ede9a70e83bfdbc53f339c7d618fa3aa46 /clang/lib/Sema/SemaLambda.cpp | |
parent | c42d243ace4933afbc1e2922dc7d326e1bdfe69f (diff) | |
download | bcm5719-llvm-2589b9808e2a08ee51b2b0e03164303d2b74c6ed.tar.gz bcm5719-llvm-2589b9808e2a08ee51b2b0e03164303d2b74c6ed.zip |
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.
llvm-svn: 160705
Diffstat (limited to 'clang/lib/Sema/SemaLambda.cpp')
-rw-r--r-- | clang/lib/Sema/SemaLambda.cpp | 28 |
1 files changed, 10 insertions, 18 deletions
diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index 25d27f44eec..3a10c2af915 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/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 |