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
diff --git a/lib/Sema/SemaLambda.cpp b/lib/Sema/SemaLambda.cpp
index 25d27f4..3a10c2a 100644
--- a/lib/Sema/SemaLambda.cpp
+++ b/lib/Sema/SemaLambda.cpp
@@ -375,6 +375,7 @@
   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 @@
                                            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 @@
         // 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 @@
   }
   finishLambdaExplicitCaptures(LSI);
 
+  LSI->ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack;
+
   // Add lambda parameters into scope.
   addLambdaParameters(Method, CurScope);
 
@@ -743,6 +732,7 @@
   bool ExplicitParams;
   bool ExplicitResultType;
   bool LambdaExprNeedsCleanups;
+  bool ContainsUnexpandedParameterPack;
   llvm::SmallVector<VarDecl *, 4> ArrayIndexVars;
   llvm::SmallVector<unsigned, 4> ArrayIndexStarts;
   {
@@ -753,6 +743,7 @@
     ExplicitParams = LSI->ExplicitParams;
     ExplicitResultType = !LSI->HasImplicitReturnType;
     LambdaExprNeedsCleanups = LSI->ExprNeedsCleanups;
+    ContainsUnexpandedParameterPack = LSI->ContainsUnexpandedParameterPack;
     ArrayIndexVars.swap(LSI->ArrayIndexVars);
     ArrayIndexStarts.swap(LSI->ArrayIndexStarts);
     
@@ -867,7 +858,8 @@
                                           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