Implement a rudimentary form of generic lambdas.

Specifically, the following features are not included in this commit:
  - any sort of capturing within generic lambdas 
  - nested lambdas
  - conversion operator for captureless lambdas
  - ensuring all visitors are generic lambda aware


As an example of what compiles:

template <class F1, class F2>
struct overload : F1, F2 {
    using F1::operator();
    using F2::operator();
    overload(F1 f1, F2 f2) : F1(f1), F2(f2) { }
  };

  auto Recursive = [](auto Self, auto h, auto ... rest) {
    return 1 + Self(Self, rest...);
  };
  auto Base = [](auto Self, auto h) {
      return 1;
  };
  overload<decltype(Base), decltype(Recursive)> O(Base, Recursive);
  int num_params =  O(O, 5, 3, "abc", 3.14, 'a');

Please see attached tests for more examples.

Some implementation notes:

  - Add a new Declarator context => LambdaExprParameterContext to 
    clang::Declarator to allow the use of 'auto' in declaring generic
    lambda parameters
    
  - Augment AutoType's constructor (similar to how variadic 
    template-type-parameters ala TemplateTypeParmDecl are implemented) to 
    accept an IsParameterPack to encode a generic lambda parameter pack.
  
  - Add various helpers to CXXRecordDecl to facilitate identifying
    and querying a closure class
  
  - LambdaScopeInfo (which maintains the current lambda's Sema state)
    was augmented to house the current depth of the template being
    parsed (id est the Parser calls Sema::RecordParsingTemplateParameterDepth)
    so that Sema::ActOnLambdaAutoParameter may use it to create the 
    appropriate list of corresponding TemplateTypeParmDecl for each
    auto parameter identified within the generic lambda (also stored
    within the current LambdaScopeInfo).  Additionally, 
    a TemplateParameterList data-member was added to hold the invented
    TemplateParameterList AST node which will be much more useful
    once we teach TreeTransform how to transform generic lambdas.
    
  - SemaLambda.h was added to hold some common lambda utility
    functions (this file is likely to grow ...)
    
  - Teach Sema::ActOnStartOfFunctionDef to check whether it
    is being called to instantiate a generic lambda's call
    operator, and if so, push an appropriately prepared
    LambdaScopeInfo object on the stack.
    
  - Teach Sema::ActOnStartOfLambdaDefinition to set the
    return type of a lambda without a trailing return type
    to 'auto' in C++1y mode, and teach the return type
    deduction machinery in SemaStmt.cpp to process either
    C++11 and C++14 lambda's correctly depending on the flag.    

  - various tests were added - but much more will be needed.

A greatful thanks to all reviewers including Eli Friedman,  
James Dennett and the ever illuminating Richard Smith.  And 
yet I am certain that I have allowed unidentified bugs to creep in; 
bugs, that I will do my best to slay, once identified!

Thanks!




git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@188977 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index 6cc596c..aab0389 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -1007,10 +1007,17 @@
                                               BlockScope, Block));
 }
 
-void Sema::PushLambdaScope(CXXRecordDecl *Lambda,
-                           CXXMethodDecl *CallOperator) {
-  FunctionScopes.push_back(new LambdaScopeInfo(getDiagnostics(), Lambda,
-                                               CallOperator));
+void Sema::PushLambdaScope() {
+  FunctionScopes.push_back(new LambdaScopeInfo(getDiagnostics()));
+}
+
+void Sema::RecordParsingTemplateParameterDepth(unsigned Depth) {
+  if (LambdaScopeInfo *const LSI = getCurLambda()) {
+    LSI->AutoTemplateParameterDepth = Depth;
+    return;
+  } 
+  assert(false && 
+      "Remove assertion if intentionally called in a non-lambda context.");
 }
 
 void Sema::PopFunctionScopeInfo(const AnalysisBasedWarnings::Policy *WP,
@@ -1066,6 +1073,16 @@
 
   return dyn_cast<LambdaScopeInfo>(FunctionScopes.back());
 }
+// We have a generic lambda if we parsed auto parameters, or we have 
+// an associated template parameter list.
+LambdaScopeInfo *Sema::getCurGenericLambda() {
+  if (LambdaScopeInfo *LSI =  getCurLambda()) {
+    return (LSI->AutoTemplateParams.size() ||
+                    LSI->GLTemplateParameterList) ? LSI : 0;
+  }
+  return 0;
+}
+
 
 void Sema::ActOnComment(SourceRange Comment) {
   if (!LangOpts.RetainCommentsFromSystemHeaders &&
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 80863e3..d5d8904 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -35,6 +35,7 @@
 #include "clang/Sema/DeclSpec.h"
 #include "clang/Sema/DelayedDiagnostic.h"
 #include "clang/Sema/Initialization.h"
+#include "clang/Sema/SemaLambda.h"
 #include "clang/Sema/Lookup.h"
 #include "clang/Sema/ParsedTemplate.h"
 #include "clang/Sema/Scope.h"
@@ -8909,6 +8910,7 @@
   const DeclSpec &DS = D.getDeclSpec();
 
   // Verify C99 6.7.5.3p2: The only SCS allowed is 'register'.
+
   // C++03 [dcl.stc]p2 also permits 'auto'.
   VarDecl::StorageClass StorageClass = SC_None;
   if (DS.getStorageClassSpec() == DeclSpec::SCS_register) {
@@ -9015,6 +9017,14 @@
   if (New->hasAttr<BlocksAttr>()) {
     Diag(New->getLocation(), diag::err_block_on_nonlocal);
   }
+
+  // Handle 'auto' within a generic lambda.
+  QualType ParamType = New->getType();
+  if (getLangOpts().CPlusPlus1y && ParamType->getContainedAutoType()) { 
+    assert(getCurLambda() && 
+                  "'auto' in parameter type only allowed in lambdas!");
+    New = ActOnLambdaAutoParameter(New);
+  } 
   return New;
 }
 
@@ -9268,9 +9278,38 @@
     FD = FunTmpl->getTemplatedDecl();
   else
     FD = cast<FunctionDecl>(D);
+  // If we are instantiating a generic lambda call operator, push
+  // a LambdaScopeInfo onto the function stack.  But use the information
+  // that's already been calculated (ActOnLambdaExpr) when analyzing the
+  // template version, to prime the current LambdaScopeInfo. 
+  if (getLangOpts().CPlusPlus1y 
+                        && isGenericLambdaCallOperatorSpecialization(D)) {
+    CXXMethodDecl *CallOperator = cast<CXXMethodDecl>(D);
+    CXXRecordDecl *LambdaClass = CallOperator->getParent();
+    LambdaExpr    *LE = LambdaClass->getLambdaExpr();
+    assert(LE && 
+     "No LambdaExpr of closure class when instantiating a generic lambda!");
+    assert(ActiveTemplateInstantiations.size() &&
+      "There should be an active template instantiation on the stack " 
+      "when instantiating a generic lambda!");
+    PushLambdaScope();
+    LambdaScopeInfo *LSI = getCurLambda();
+    LSI->CallOperator = CallOperator;
+    LSI->Lambda = LambdaClass;
+    LSI->ReturnType = CallOperator->getResultType();
 
-  // Enter a new function scope
-  PushFunctionScope();
+    if (LE->getCaptureDefault() == LCD_None)
+      LSI->ImpCaptureStyle = CapturingScopeInfo::ImpCap_None;
+    else if (LE->getCaptureDefault() == LCD_ByCopy)
+      LSI->ImpCaptureStyle = CapturingScopeInfo::ImpCap_LambdaByval;
+    else if (LE->getCaptureDefault() == LCD_ByRef)
+      LSI->ImpCaptureStyle = CapturingScopeInfo::ImpCap_LambdaByref;
+    
+    LSI->IntroducerRange = LE->getIntroducerRange();
+  }
+  else
+    // Enter a new function scope
+    PushFunctionScope();
 
   // See if this is a redefinition.
   if (!FD->isLateTemplateParsed())
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 6ebfb57..bde9c15 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -32,6 +32,7 @@
 #include "clang/Sema/CXXFieldCollector.h"
 #include "clang/Sema/DeclSpec.h"
 #include "clang/Sema/Initialization.h"
+#include "clang/Sema/SemaLambda.h"
 #include "clang/Sema/Lookup.h"
 #include "clang/Sema/ParsedTemplate.h"
 #include "clang/Sema/Scope.h"
@@ -10015,29 +10016,27 @@
        SourceLocation CurrentLocation,
        CXXConversionDecl *Conv) 
 {
-  CXXRecordDecl *Lambda = Conv->getParent();
+  CXXRecordDecl *LambdaClass = Conv->getParent();
   
   // Make sure that the lambda call operator is marked used.
-  markLambdaCallOperatorUsed(*this, Lambda);
+  markLambdaCallOperatorUsed(*this, LambdaClass);
   
   Conv->setUsed();
   
   SynthesizedFunctionScope Scope(*this, Conv);
   DiagnosticErrorTrap Trap(Diags);
   
-  // Return the address of the __invoke function.
-  DeclarationName InvokeName = &Context.Idents.get("__invoke");
-  CXXMethodDecl *Invoke 
-    = cast<CXXMethodDecl>(Lambda->lookup(InvokeName).front());
+  CXXMethodDecl *Invoke = LambdaClass->getLambdaStaticInvoker();
+
   Expr *FunctionRef = BuildDeclRefExpr(Invoke, Invoke->getType(),
                                        VK_LValue, Conv->getLocation()).take();
-  assert(FunctionRef && "Can't refer to __invoke function?");
+  assert(FunctionRef && "Can't refer to lambda static invoker function?");
   Stmt *Return = ActOnReturnStmt(Conv->getLocation(), FunctionRef).take();
   Conv->setBody(new (Context) CompoundStmt(Context, Return,
                                            Conv->getLocation(),
                                            Conv->getLocation()));
     
-  // Fill in the __invoke function with a dummy implementation. IR generation
+  // Fill in the invoke function with a dummy implementation. IR generation
   // will fill in the actual details.
   Invoke->setUsed();
   Invoke->setReferenced();
diff --git a/lib/Sema/SemaLambda.cpp b/lib/Sema/SemaLambda.cpp
index ae3a938..bed71a6 100644
--- a/lib/Sema/SemaLambda.cpp
+++ b/lib/Sema/SemaLambda.cpp
@@ -14,6 +14,7 @@
 #include "clang/AST/ExprCXX.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Sema/Initialization.h"
+#include "clang/Sema/SemaLambda.h"
 #include "clang/Sema/Lookup.h"
 #include "clang/Sema/Scope.h"
 #include "clang/Sema/ScopeInfo.h"
@@ -120,11 +121,69 @@
   llvm_unreachable("unexpected context");
 }
 
+
+ParmVarDecl *Sema::ActOnLambdaAutoParameter(ParmVarDecl *PVD) {
+  LambdaScopeInfo *LSI = getCurLambda();
+  assert(LSI && "No LambdaScopeInfo on the stack!");
+  const unsigned TemplateParameterDepth = LSI->AutoTemplateParameterDepth;
+  const unsigned AutoParameterPosition = LSI->AutoTemplateParams.size();
+  // Invent a template type parameter corresponding to the auto 
+  // containing parameter.
+  TemplateTypeParmDecl *TemplateParam =
+    TemplateTypeParmDecl::Create(Context, 
+      // Temporarily add to the TranslationUnit DeclContext.  When the 
+      // associated TemplateParameterList is attached to a template
+      // declaration (such as FunctionTemplateDecl), the DeclContext 
+      // for each template parameter gets updated appropriately via
+      // a call to AdoptTemplateParameterList. 
+      Context.getTranslationUnitDecl(), 
+      SourceLocation(), 
+      PVD->getLocation(), 
+      TemplateParameterDepth, 
+      AutoParameterPosition,  // our template param index 
+      /* Identifier*/ 0, false, PVD->isParameterPack());
+  LSI->AutoTemplateParams.push_back(TemplateParam);
+  QualType AutoTy = PVD->getType();
+  // Now replace the 'auto' in the function parameter with this invented 
+  // template type parameter.
+  QualType TemplParamType = QualType(TemplateParam->getTypeForDecl(), 0);    
+  
+  TypeSourceInfo *AutoTSI = PVD->getTypeSourceInfo();
+  TypeSourceInfo *NewTSI = SubstAutoTypeSourceInfo(AutoTSI, TemplParamType);
+  PVD->setType(NewTSI->getType());
+  PVD->setTypeSourceInfo(NewTSI);
+  return PVD;
+}
+
+
+static inline TemplateParameterList *
+              getGenericLambdaTemplateParameterList(LambdaScopeInfo *LSI, 
+                            Sema &SemaRef) {
+  if (LSI->GLTemplateParameterList)
+    return LSI->GLTemplateParameterList;
+  else if (LSI->AutoTemplateParams.size()) {
+    SourceRange IntroRange = LSI->IntroducerRange;
+    SourceLocation LAngleLoc = IntroRange.getBegin();
+    SourceLocation RAngleLoc = IntroRange.getEnd();
+    LSI->GLTemplateParameterList = 
+          TemplateParameterList::Create(SemaRef.Context, 
+            /* Template kw loc */ SourceLocation(), 
+            LAngleLoc,
+            (NamedDecl**)LSI->AutoTemplateParams.data(), 
+            LSI->AutoTemplateParams.size(), RAngleLoc);  
+  }
+  return LSI->GLTemplateParameterList;
+}
+
+
+
 CXXMethodDecl *Sema::startLambdaDefinition(CXXRecordDecl *Class,
                  SourceRange IntroducerRange,
                  TypeSourceInfo *MethodType,
                  SourceLocation EndLoc,
                  ArrayRef<ParmVarDecl *> Params) {
+  TemplateParameterList *TemplateParams = 
+            getGenericLambdaTemplateParameterList(getCurLambda(), *this);
   // C++11 [expr.prim.lambda]p5:
   //   The closure type for a lambda-expression has a public inline function 
   //   call operator (13.5.4) whose parameters and return type are described by
@@ -152,6 +211,17 @@
   // Temporarily set the lexical declaration context to the current
   // context, so that the Scope stack matches the lexical nesting.
   Method->setLexicalDeclContext(CurContext);  
+  // Create a function template if we have a template parameter list
+  FunctionTemplateDecl *const TemplateMethod = TemplateParams ?
+            FunctionTemplateDecl::Create(Context, Class,
+                                         Method->getLocation(), MethodName, 
+                                         TemplateParams,
+                                         Method) : 0;
+  if (TemplateMethod) {
+    TemplateMethod->setLexicalDeclContext(CurContext);
+    TemplateMethod->setAccess(AS_public);
+    Method->setDescribedFunctionTemplate(TemplateMethod);
+  }
   
   // Add parameters.
   if (!Params.empty()) {
@@ -177,15 +247,16 @@
   return Method;
 }
 
-LambdaScopeInfo *Sema::enterLambdaScope(CXXMethodDecl *CallOperator,
+void Sema::buildLambdaScope(LambdaScopeInfo *LSI,
+                                        CXXMethodDecl *CallOperator,
                                         SourceRange IntroducerRange,
                                         LambdaCaptureDefault CaptureDefault,
                                         SourceLocation CaptureDefaultLoc,
                                         bool ExplicitParams,
                                         bool ExplicitResultType,
                                         bool Mutable) {
-  PushLambdaScope(CallOperator->getParent(), CallOperator);
-  LambdaScopeInfo *LSI = getCurLambda();
+  LSI->CallOperator = CallOperator;
+  LSI->Lambda = CallOperator->getParent();
   if (CaptureDefault == LCD_ByCopy)
     LSI->ImpCaptureStyle = LambdaScopeInfo::ImpCap_LambdaByval;
   else if (CaptureDefault == LCD_ByRef)
@@ -208,8 +279,6 @@
   } else {
     LSI->HasImplicitReturnType = true;
   }
-
-  return LSI;
 }
 
 void Sema::finishLambdaExplicitCaptures(LambdaScopeInfo *LSI) {
@@ -358,7 +427,7 @@
 }
 
 void Sema::deduceClosureReturnType(CapturingScopeInfo &CSI) {
-  assert(CSI.HasImplicitReturnType);
+  assert(CSI.HasImplicitReturnType || CSI.ReturnType->isUndeducedType());
 
   // C++ Core Issue #975, proposed resolution:
   //   If a lambda-expression does not include a trailing-return-type,
@@ -392,7 +461,7 @@
   // Second case: at least one return statement has dependent type.
   // Delay type checking until instantiation.
   assert(!CSI.ReturnType.isNull() && "We should have a tentative return type.");
-  if (CSI.ReturnType->isDependentType())
+  if (CSI.ReturnType->isDependentType() || CSI.ReturnType->isUndeducedType())
     return;
 
   // Try to apply the enum-fuzz rule.
@@ -519,15 +588,25 @@
 }
 
 void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
-                                        Declarator &ParamInfo,
-                                        Scope *CurScope) {
+                  Declarator &ParamInfo, Scope *CurScope) {
   // Determine if we're within a context where we know that the lambda will
   // be dependent, because there are template parameters in scope.
   bool KnownDependent = false;
-  if (Scope *TmplScope = CurScope->getTemplateParamParent())
-    if (!TmplScope->decl_empty())
+  LambdaScopeInfo *const LSI = getCurLambda();
+  assert(LSI && "LambdaScopeInfo should be on stack!");
+  TemplateParameterList *TemplateParams = 
+            getGenericLambdaTemplateParameterList(LSI, *this);
+
+  if (Scope *TmplScope = CurScope->getTemplateParamParent()) {
+    // Since we have our own TemplateParams, so check if an outer scope
+    // has template params, only then are we in a dependent scope.
+    if (TemplateParams)  {
+      TmplScope = TmplScope->getParent();
+      TmplScope = TmplScope ? TmplScope->getTemplateParamParent() : 0;
+    }
+    if (TmplScope && !TmplScope->decl_empty())
       KnownDependent = true;
-  
+  }
   // Determine the signature of the call operator.
   TypeSourceInfo *MethodTyInfo;
   bool ExplicitParams = true;
@@ -542,7 +621,11 @@
     FunctionProtoType::ExtProtoInfo EPI;
     EPI.HasTrailingReturn = true;
     EPI.TypeQuals |= DeclSpec::TQ_const;
-    QualType MethodTy = Context.getFunctionType(Context.DependentTy, None,
+    // For C++1y, use the new return type deduction machinery, by imaginging
+    // 'auto' if no trailing return type.
+    QualType DefaultTypeForNoTrailingReturn = getLangOpts().CPlusPlus1y ?
+                    Context.getAutoDeductType() : Context.DependentTy;
+    QualType MethodTy = Context.getFunctionType(DefaultTypeForNoTrailingReturn, None,
                                                 EPI);
     MethodTyInfo = Context.getTrivialTypeSourceInfo(MethodTy);
     ExplicitParams = false;
@@ -560,14 +643,15 @@
     if (!FTI.hasMutableQualifier())
       FTI.TypeQuals |= DeclSpec::TQ_const;
     
+    ExplicitResultType = FTI.hasTrailingReturnType();
+    // In C++11 if there is no explicit return type, the return type is
+    // artificially set to DependentTy, whereas in C++1y it is set to AutoTy
+    // (through ConvertDeclSpecToType) which allows us to support both
+    // C++11 and C++1y return type deduction semantics.
     MethodTyInfo = GetTypeForDeclarator(ParamInfo, CurScope);
     assert(MethodTyInfo && "no type from lambda-declarator");
     EndLoc = ParamInfo.getSourceRange().getEnd();
     
-    ExplicitResultType
-      = MethodTyInfo->getType()->getAs<FunctionType>()->getResultType() 
-                                                        != Context.DependentTy;
-
     if (FTI.NumArgs == 1 && !FTI.isVariadic && FTI.ArgInfo[0].Ident == 0 &&
         cast<ParmVarDecl>(FTI.ArgInfo[0].Param)->getType()->isVoidType()) {
       // Empty arg list, don't push any params.
@@ -588,7 +672,6 @@
 
   CXXMethodDecl *Method = startLambdaDefinition(Class, Intro.Range,
                                                 MethodTyInfo, EndLoc, Params);
-  
   if (ExplicitParams)
     CheckCXXDefaultArguments(Method);
   
@@ -598,9 +681,8 @@
   // Introduce the function call operator as the current declaration context.
   PushDeclContext(CurScope, Method);
     
-  // Introduce the lambda scope.
-  LambdaScopeInfo *LSI
-    = enterLambdaScope(Method,
+  // Build the lambda scope.
+  buildLambdaScope(LSI, Method,
                        Intro.Range,
                        Intro.Default, Intro.DefaultLoc,
                        ExplicitParams,
@@ -812,6 +894,8 @@
                                          SourceRange IntroducerRange,
                                          CXXRecordDecl *Class,
                                          CXXMethodDecl *CallOperator) {
+  // FIXME: The conversion operator needs to be fixed for generic lambdas.
+  if (Class->isGenericLambda()) return;
   // Add the conversion to function pointer.
   const FunctionProtoType *Proto
     = CallOperator->getType()->getAs<FunctionProtoType>(); 
@@ -849,10 +933,9 @@
   Conversion->setAccess(AS_public);
   Conversion->setImplicit(true);
   Class->addDecl(Conversion);
-  
-  // Add a non-static member function "__invoke" that will be the result of
-  // the conversion.
-  Name = &S.Context.Idents.get("__invoke");
+  // Add a non-static member function that will be the result of
+  // the conversion with a certain unique ID.
+  Name = &S.Context.Idents.get(getLambdaStaticInvokerName());
   CXXMethodDecl *Invoke
     = CXXMethodDecl::Create(S.Context, Class, Loc, 
                             DeclarationNameInfo(Name, Loc), FunctionTy, 
@@ -1000,8 +1083,11 @@
     //   If a lambda-expression does not include a
     //   trailing-return-type, it is as if the trailing-return-type
     //   denotes the following type:
+    // Skip for C++1y return type deduction semantics which uses
+    // different machinery currently.
+    // FIXME: Refactor and Merge the return type deduction machinery.
     // FIXME: Assumes current resolution to core issue 975.
-    if (LSI->HasImplicitReturnType) {
+    if (LSI->HasImplicitReturnType && !getLangOpts().CPlusPlus1y) {
       deduceClosureReturnType(*LSI);
 
       //   - if there are no return statements in the
@@ -1019,13 +1105,18 @@
           LSI->ReturnType, Proto->getArgTypes(), Proto->getExtProtoInfo());
       CallOperator->setType(FunctionTy);
     }
-
     // C++ [expr.prim.lambda]p7:
     //   The lambda-expression's compound-statement yields the
     //   function-body (8.4) of the function call operator [...].
     ActOnFinishFunctionBody(CallOperator, Body, IsInstantiation);
     CallOperator->setLexicalDeclContext(Class);
-    Class->addDecl(CallOperator);
+    Decl *TemplateOrNonTemplateCallOperatorDecl = 
+      !CallOperator->getDescribedFunctionTemplate() ? cast<Decl>(CallOperator)
+        : CallOperator->getDescribedFunctionTemplate();
+
+    TemplateOrNonTemplateCallOperatorDecl->setLexicalDeclContext(Class);
+    Class->addDecl(TemplateOrNonTemplateCallOperatorDecl);
+
     PopExpressionEvaluationContext();
 
     // C++11 [expr.prim.lambda]p6:
@@ -1065,7 +1156,7 @@
                                           CaptureInits, ArrayIndexVars, 
                                           ArrayIndexStarts, Body->getLocEnd(),
                                           ContainsUnexpandedParameterPack);
-
+  Class->setLambdaExpr(Lambda);
   // C++11 [expr.prim.lambda]p2:
   //   A lambda-expression shall not appear in an unevaluated operand
   //   (Clause 5).
@@ -1085,7 +1176,15 @@
       break;
     }
   }
-  
+  // TODO: Implement capturing.
+  if (Lambda->isGenericLambda()) {
+    if (Lambda->getCaptureDefault() != LCD_None) {
+      Diag(Lambda->getIntroducerRange().getBegin(), 
+        diag::err_glambda_not_fully_implemented) 
+        << " capturing not implemented yet";
+      return ExprError();
+    }
+  }
   return MaybeBindToTemporary(Lambda);
 }
 
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 06d1f0b..33dbf14 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -8670,6 +8670,10 @@
         }
       }
     }
+    // FIXME: For generic lambda parameters, check if the function is a lambda
+    // call operator, and if so, emit a prettier and more informative 
+    // diagnostic that mentions 'auto' and lambda in addition to 
+    // (or instead of?) the canonical template type parameters.
     S.Diag(Templated->getLocation(),
            diag::note_ovl_candidate_non_deduced_mismatch)
         << FirstTA << SecondTA;
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index 0570a60..5434e98 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -2487,12 +2487,31 @@
   // [expr.prim.lambda]p4 in C++11; block literals follow the same rules.
   CapturingScopeInfo *CurCap = cast<CapturingScopeInfo>(getCurFunction());
   QualType FnRetType = CurCap->ReturnType;
-
-  // For blocks/lambdas with implicit return types, we check each return
-  // statement individually, and deduce the common return type when the block
-  // or lambda is completed.
-  if (CurCap->HasImplicitReturnType) {
-    // FIXME: Fold this into the 'auto' codepath below.
+  LambdaScopeInfo *const LambdaSI = getCurLambda();
+  // In C++1y, an implicit return type behaves as if 'auto' was
+  // the return type.
+  if (FnRetType.isNull() && getLangOpts().CPlusPlus1y) {
+    if (LambdaSI) {
+      FunctionDecl *CallOp = LambdaSI->CallOperator; 
+      FnRetType = CallOp->getResultType();
+      assert(FnRetType->getContainedAutoType());
+    }
+  }
+  
+  // For blocks/lambdas with implicit return types in C++11, we check each 
+  // return statement individually, and deduce the common return type when 
+  // the block or lambda is completed.  In C++1y, the return type deduction
+  // of a lambda is specified in terms of auto.
+  // Notably, in C++11, we take the type of the expression after decay and
+  // lvalue-to-rvalue conversion, so a class type can be cv-qualified.
+  // In C++1y, we perform template argument deduction as if the return
+  // type were 'auto', so an implicit return type is never cv-qualified.
+  // i.e if (getLangOpts().CPlusPlus1y && FnRetType.hasQualifiers())
+  //   FnRetType = FnRetType.getUnqualifiedType();
+  // Return type deduction is unchanged for blocks in C++1y.
+  // FIXME: Fold this into the 'auto' codepath below.
+  if (CurCap->HasImplicitReturnType && 
+                            (!LambdaSI || !getLangOpts().CPlusPlus1y)) {
     if (RetValExp && !isa<InitListExpr>(RetValExp)) {
       ExprResult Result = DefaultFunctionArrayLvalueConversion(RetValExp);
       if (Result.isInvalid())
@@ -2500,13 +2519,7 @@
       RetValExp = Result.take();
 
       if (!CurContext->isDependentContext()) {
-        FnRetType = RetValExp->getType();
-        // In C++11, we take the type of the expression after decay and
-        // lvalue-to-rvalue conversion, so a class type can be cv-qualified.
-        // In C++1y, we perform template argument deduction as if the return
-        // type were 'auto', so an implicit return type is never cv-qualified.
-        if (getLangOpts().CPlusPlus1y && FnRetType.hasQualifiers())
-          FnRetType = FnRetType.getUnqualifiedType();
+        FnRetType = RetValExp->getType();       
       } else
         FnRetType = CurCap->ReturnType = Context.DependentTy;
     } else {
@@ -2517,7 +2530,6 @@
         Diag(ReturnLoc, diag::err_lambda_return_init_list)
           << RetValExp->getSourceRange();
       }
-
       FnRetType = Context.VoidTy;
     }
 
@@ -2526,7 +2538,8 @@
     if (CurCap->ReturnType.isNull())
       CurCap->ReturnType = FnRetType;
   } else if (AutoType *AT =
-                 FnRetType.isNull() ? 0 : FnRetType->getContainedAutoType()) {
+                 (FnRetType.isNull() || !LambdaSI) ? 0 
+                      : FnRetType->getContainedAutoType()) {
     // In C++1y, the return type may involve 'auto'.
     FunctionDecl *FD = cast<LambdaScopeInfo>(CurCap)->CallOperator;
     if (CurContext->isDependentContext()) {
@@ -2534,7 +2547,7 @@
       //   Return type deduction [...] occurs when the definition is
       //   instantiated even if the function body contains a return
       //   statement with a non-type-dependent operand.
-      CurCap->ReturnType = FnRetType = Context.DependentTy;
+      CurCap->ReturnType = FnRetType;
     } else if (DeduceFunctionTypeFromReturnExpr(FD, ReturnLoc, RetValExp, AT)) {
       FD->setInvalidDecl();
       return StmtError();
@@ -2564,7 +2577,7 @@
   // pickier with blocks than for normal functions because we don't have GCC
   // compatibility to worry about here.
   const VarDecl *NRVOCandidate = 0;
-  if (FnRetType->isDependentType()) {
+  if (FnRetType->isDependentType() || FnRetType->isUndeducedType()) {
     // Delay processing for now.  TODO: there are lots of dependent
     // types we can conclusively prove aren't void.
   } else if (FnRetType->isVoidType()) {
@@ -2624,7 +2637,6 @@
 
   return Owned(Result);
 }
-
 /// Deduce the return type for a function from a returned expression, per
 /// C++1y [dcl.spec.auto]p6.
 bool Sema::DeduceFunctionTypeFromReturnExpr(FunctionDecl *FD,
@@ -2634,7 +2646,6 @@
   TypeLoc OrigResultType = FD->getTypeSourceInfo()->getTypeLoc().
     IgnoreParens().castAs<FunctionProtoTypeLoc>().getResultLoc();
   QualType Deduced;
-
   if (RetExpr && isa<InitListExpr>(RetExpr)) {
     //  If the deduction is for a return statement and the initializer is
     //  a braced-init-list, the program is ill-formed.
@@ -2692,9 +2703,18 @@
     AutoType *NewAT = Deduced->getContainedAutoType();
     if (!FD->isDependentContext() &&
         !Context.hasSameType(AT->getDeducedType(), NewAT->getDeducedType())) {
-      Diag(ReturnLoc, diag::err_auto_fn_different_deductions)
-        << (AT->isDecltypeAuto() ? 1 : 0)
-        << NewAT->getDeducedType() << AT->getDeducedType();
+      LambdaScopeInfo *const LambdaSI = getCurLambda();
+      if (LambdaSI && LambdaSI->HasImplicitReturnType) {
+        Diag(ReturnLoc,
+          diag::err_typecheck_missing_return_type_incompatible)
+          << NewAT->getDeducedType() << AT->getDeducedType()
+          << true /*IsLambda*/;
+      }
+      else {  
+        Diag(ReturnLoc, diag::err_auto_fn_different_deductions)
+          << (AT->isDecltypeAuto() ? 1 : 0)
+          << NewAT->getDeducedType() << AT->getDeducedType();
+      }
       return true;
     }
   } else if (!FD->isInvalidDecl()) {
@@ -2710,10 +2730,8 @@
   // Check for unexpanded parameter packs.
   if (RetValExp && DiagnoseUnexpandedParameterPack(RetValExp))
     return StmtError();
-
   if (isa<CapturingScopeInfo>(getCurFunction()))
     return ActOnCapScopeReturnStmt(ReturnLoc, RetValExp);
-
   QualType FnRetType;
   QualType RelatedRetType;
   if (const FunctionDecl *FD = getCurFunctionDecl()) {
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp
index c8669ae..813f71d 100644
--- a/lib/Sema/SemaTemplateDeduction.cpp
+++ b/lib/Sema/SemaTemplateDeduction.cpp
@@ -3766,7 +3766,8 @@
         QualType Result =
           SemaRef.Context.getAutoType(Dependent ? QualType() : Replacement,
                                       TL.getTypePtr()->isDecltypeAuto(),
-                                      Dependent);
+                                      Dependent, TL.getTypePtr()->
+                                        containsUnexpandedParameterPack());
         AutoTypeLoc NewTL = TLB.push<AutoTypeLoc>(Result);
         NewTL.setNameLoc(TL.getNameLoc());
         return Result;
@@ -3907,8 +3908,16 @@
   return DAR_Succeeded;
 }
 
-QualType Sema::SubstAutoType(QualType Type, QualType Deduced) {
-  return SubstituteAutoTransform(*this, Deduced).TransformType(Type);
+QualType Sema::SubstAutoType(QualType TypeWithAuto, 
+                             QualType TypeToReplaceAuto) {
+  return SubstituteAutoTransform(*this, TypeToReplaceAuto).
+               TransformType(TypeWithAuto);
+}
+
+TypeSourceInfo* Sema::SubstAutoTypeSourceInfo(TypeSourceInfo *TypeWithAuto, 
+                             QualType TypeToReplaceAuto) {
+    return SubstituteAutoTransform(*this, TypeToReplaceAuto).
+               TransformType(TypeWithAuto);
 }
 
 void Sema::DiagnoseAutoDeductionFailure(VarDecl *VDecl, Expr *Init) {
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 6998827..2dabfb2 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -781,7 +781,13 @@
     // specified with a trailing return type or inferred.
     if (declarator.getContext() == Declarator::LambdaExprContext ||
         isOmittedBlockReturnType(declarator)) {
-      Result = Context.DependentTy;
+      // In C++1y (n3690 CD), 5.1.2 [expr.prim.lambda]/4 : The lambda return 
+      // type is auto, which is replaced by the trailing-return-type if 
+      // provided and/or deduced from return statements as described 
+      // in 7.1.6.4. 
+      Result = S.getLangOpts().CPlusPlus1y &&
+               declarator.getContext() == Declarator::LambdaExprContext 
+                  ? Context.getAutoDeductType() : Context.DependentTy;
       break;
     }
 
@@ -1006,11 +1012,17 @@
 
   case DeclSpec::TST_auto:
     // TypeQuals handled by caller.
-    Result = Context.getAutoType(QualType(), /*decltype(auto)*/false);
+    Result = Context.getAutoType(QualType(), 
+                                /*decltype(auto)*/false, 
+                                /*IsDependent*/   false, 
+                                /*IsParameterPack*/ declarator.hasEllipsis());
     break;
 
   case DeclSpec::TST_decltype_auto:
-    Result = Context.getAutoType(QualType(), /*decltype(auto)*/true);
+    Result = Context.getAutoType(QualType(), 
+                                 /*decltype(auto)*/true, 
+                                 /*IsDependent*/   false, 
+                                 /*IsParameterPack*/ false);
     break;
 
   case DeclSpec::TST_unknown_anytype:
@@ -1557,7 +1569,7 @@
         ASM = ArrayType::Normal;
       }
     } else if (!T->isDependentType() && !T->isVariablyModifiedType() &&
-               !T->isIncompleteType()) {
+               !T->isIncompleteType() && !T->isUndeducedType()) {
       // Is the array too large?
       unsigned ActiveSizeBits
         = ConstantArrayType::getNumAddressingBits(Context, T, ConstVal);
@@ -2097,6 +2109,7 @@
   // In C++11, a function declarator using 'auto' must have a trailing return
   // type (this is checked later) and we can skip this. In other languages
   // using auto, we need to check regardless.
+  // Generic Lambdas (C++14) allow 'auto' in their parameters.
   if (ContainsPlaceholderType &&
       (!SemaRef.getLangOpts().CPlusPlus11 || !D.isFunctionDeclarator())) {
     int Error = -1;
@@ -2109,7 +2122,12 @@
     case Declarator::ObjCParameterContext:
     case Declarator::ObjCResultContext:
     case Declarator::PrototypeContext:
-      Error = 0; // Function prototype
+      Error = 0;  
+      break;
+    case Declarator::LambdaExprParameterContext:
+      if (!(SemaRef.getLangOpts().CPlusPlus1y 
+              && D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto))
+        Error = 0;
       break;
     case Declarator::MemberContext:
       if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static)
@@ -2189,8 +2207,13 @@
       AutoRange = D.getName().getSourceRange();
 
     if (Error != -1) {
+      if (D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_decltype_auto) {
+        SemaRef.Diag(AutoRange.getBegin(), 
+            diag::err_decltype_auto_function_declarator_not_declaration);
+      } else {
       SemaRef.Diag(AutoRange.getBegin(), diag::err_auto_not_allowed)
         << Error << AutoRange;
+      }
       T = SemaRef.Context.IntTy;
       D.setInvalidType(true);
     } else
@@ -2240,6 +2263,7 @@
       D.setInvalidType(true);
       break;
     case Declarator::PrototypeContext:
+    case Declarator::LambdaExprParameterContext:
     case Declarator::ObjCParameterContext:
     case Declarator::ObjCResultContext:
     case Declarator::KNRTypeListContext:
@@ -2613,8 +2637,11 @@
           }
         }
       }
-
-      if (const AutoType *AT = T->getContainedAutoType()) {
+      const AutoType *AT = T->getContainedAutoType();
+      // Allow arrays of auto if we are a generic lambda parameter.
+      // i.e. [](auto (&array)[5]) { return array[0]; }; OK
+      if (AT && !(S.getLangOpts().CPlusPlus1y && 
+                  D.getContext() == Declarator::LambdaExprParameterContext)) {
         // We've already diagnosed this for decltype(auto).
         if (!AT->isDecltypeAuto())
           S.Diag(DeclType.Loc, diag::err_illegal_decl_array_of_auto)
@@ -3110,6 +3137,7 @@
     //   is a parameter pack (14.5.3). [...]
     switch (D.getContext()) {
     case Declarator::PrototypeContext:
+    case Declarator::LambdaExprParameterContext:
       // C++0x [dcl.fct]p13:
       //   [...] When it is part of a parameter-declaration-clause, the
       //   parameter pack is a function parameter pack (14.5.3). The type T
@@ -3128,7 +3156,6 @@
         T = Context.getPackExpansionType(T, None);
       }
       break;
-
     case Declarator::TemplateParamContext:
       // C++0x [temp.param]p15:
       //   If a template-parameter is a [...] is a parameter-declaration that
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 9e57383..6e69bdc 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -782,7 +782,10 @@
     // Note, IsDependent is always false here: we implicitly convert an 'auto'
     // which has been deduced to a dependent type into an undeduced 'auto', so
     // that we'll retry deduction after the transformation.
-    return SemaRef.Context.getAutoType(Deduced, IsDecltypeAuto);
+    // FIXME: Can we assume the same about IsParameterPack?
+    return SemaRef.Context.getAutoType(Deduced, IsDecltypeAuto, 
+                                       /*IsDependent*/ false, 
+                                       /*IsParameterPack*/ false);
   }
 
   /// \brief Build a new template specialization type.
@@ -3494,7 +3497,9 @@
         Qs.removeObjCLifetime();
         Deduced = SemaRef.Context.getQualifiedType(Deduced.getUnqualifiedType(),
                                                    Qs);
-        Result = SemaRef.Context.getAutoType(Deduced, AutoTy->isDecltypeAuto());
+        Result = SemaRef.Context.getAutoType(Deduced, AutoTy->isDecltypeAuto(), 
+                                AutoTy->isDependentType(), 
+                                AutoTy->containsUnexpandedParameterPack());
         TLB.TypeWasModifiedSafely(Result);
       } else {
         // Otherwise, complain about the addition of a qualifier to an
@@ -8193,6 +8198,14 @@
 template<typename Derived>
 ExprResult
 TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
+ 
+  // FIXME: Implement nested generic lambda transformations.
+  if (E->isGenericLambda()) {
+    getSema().Diag(E->getIntroducerRange().getBegin(), 
+      diag::err_glambda_not_fully_implemented) 
+      << " nested lambdas not implemented yet";
+    return ExprError();
+  }
   // Transform the type of the lambda parameters and start the definition of
   // the lambda itself.
   TypeSourceInfo *MethodTy
@@ -8215,7 +8228,10 @@
         E->getCallOperator()->param_size(),
         0, ParamTypes, &Params))
     return ExprError();
-
+  getSema().PushLambdaScope();
+  LambdaScopeInfo *LSI = getSema().getCurLambda();
+  // TODO: Fix for nested lambdas
+  LSI->GLTemplateParameterList = 0;
   // Build the call operator.
   CXXMethodDecl *CallOperator
     = getSema().startLambdaDefinition(Class, E->getIntroducerRange(),
@@ -8250,9 +8266,9 @@
   // Introduce the context of the call operator.
   Sema::ContextRAII SavedContext(getSema(), CallOperator);
 
+  LambdaScopeInfo *const LSI = getSema().getCurLambda();
   // Enter the scope of the lambda.
-  sema::LambdaScopeInfo *LSI
-    = getSema().enterLambdaScope(CallOperator, E->getIntroducerRange(),
+  getSema().buildLambdaScope(LSI, CallOperator, E->getIntroducerRange(),
                                  E->getCaptureDefault(),
                                  E->getCaptureDefaultLoc(),
                                  E->hasExplicitParameters(),