Revert "Implement a rudimentary form of generic lambdas."
authorManuel Klimek <klimek@google.com>
Thu, 22 Aug 2013 12:12:24 +0000 (12:12 +0000)
committerManuel Klimek <klimek@google.com>
Thu, 22 Aug 2013 12:12:24 +0000 (12:12 +0000)
This reverts commit 606f5d7a99b11957e057e4cd1f55f931f66a42c7.

llvm-svn: 189004

36 files changed:
clang/include/clang/AST/ASTContext.h
clang/include/clang/AST/DeclCXX.h
clang/include/clang/AST/ExprCXX.h
clang/include/clang/AST/Type.h
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/include/clang/Sema/DeclSpec.h
clang/include/clang/Sema/ScopeInfo.h
clang/include/clang/Sema/Sema.h
clang/include/clang/Sema/SemaLambda.h [deleted file]
clang/lib/AST/ASTContext.cpp
clang/lib/AST/ASTImporter.cpp
clang/lib/AST/DeclCXX.cpp
clang/lib/AST/ExprCXX.cpp
clang/lib/AST/Type.cpp
clang/lib/CodeGen/CodeGenFunction.cpp
clang/lib/Parse/ParseDecl.cpp
clang/lib/Parse/ParseExprCXX.cpp
clang/lib/Parse/Parser.cpp
clang/lib/Sema/Sema.cpp
clang/lib/Sema/SemaDecl.cpp
clang/lib/Sema/SemaDeclCXX.cpp
clang/lib/Sema/SemaLambda.cpp
clang/lib/Sema/SemaOverload.cpp
clang/lib/Sema/SemaStmt.cpp
clang/lib/Sema/SemaTemplateDeduction.cpp
clang/lib/Sema/SemaType.cpp
clang/lib/Sema/TreeTransform.h
clang/lib/Serialization/ASTReader.cpp
clang/lib/Serialization/ASTReaderDecl.cpp
clang/lib/Serialization/ASTWriter.cpp
clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-generic-lambda-1y.cpp [deleted file]
clang/test/CXX/expr/expr.prim/expr.prim.lambda/generic-lambda-unimplemented-1y.cpp [deleted file]
clang/test/CXX/expr/expr.prim/expr.prim.lambda/p2-generic-lambda-1y.cpp [deleted file]
clang/test/CXX/expr/expr.prim/expr.prim.lambda/p4-1y.cpp
clang/test/CXX/expr/expr.prim/expr.prim.lambda/p4.cpp
clang/test/CXX/expr/expr.prim/expr.prim.lambda/p5-generic-lambda-1y.cpp [deleted file]

index 2244d08..0e0a62b 100644 (file)
@@ -1115,7 +1115,7 @@ public:
 
   /// \brief C++11 deduced auto type.
   QualType getAutoType(QualType DeducedType, bool IsDecltypeAuto,
-                       bool IsDependent, bool IsParameterPack) const;
+                       bool IsDependent = false) const;
 
   /// \brief C++11 deduction pattern for 'auto' type.
   QualType getAutoDeductType() const;
index 9899020..f96032c 100644 (file)
@@ -516,8 +516,8 @@ class CXXRecordDecl : public RecordDecl {
     
     LambdaDefinitionData(CXXRecordDecl *D, TypeSourceInfo *Info, bool Dependent) 
       : DefinitionData(D), Dependent(Dependent), NumCaptures(0), 
-        NumExplicitCaptures(0), ManglingNumber(0), ContextDecl(0), 
-        Captures(0), MethodTyInfo(Info), TheLambdaExpr(0
+        NumExplicitCaptures(0), ManglingNumber(0), ContextDecl(0), Captures(0),
+        MethodTyInfo(Info
     {
       IsLambda = true;
     }
@@ -529,7 +529,7 @@ class CXXRecordDecl : public RecordDecl {
     /// within the default argument of a function template, because the
     /// lambda will have been created with the enclosing context as its
     /// declaration context, rather than function. This is an unfortunate
-    /// artifact of having to parse the default arguments before. 
+    /// artifact of having to parse the default arguments before 
     unsigned Dependent : 1;
     
     /// \brief The number of captures in this lambda.
@@ -554,10 +554,6 @@ class CXXRecordDecl : public RecordDecl {
 
     /// \brief The type of the call method.
     TypeSourceInfo *MethodTyInfo;
-
-    /// \brief The AST node of the lambda expression.
-    LambdaExpr *TheLambdaExpr;
-       
   };
 
   struct DefinitionData &data() {
@@ -993,36 +989,6 @@ public:
   /// \brief Determine whether this class describes a lambda function object.
   bool isLambda() const { return hasDefinition() && data().IsLambda; }
 
-  /// \brief Determine whether this class describes a generic 
-  /// lambda function object (i.e. function call operator is
-  /// a template). 
-  bool isGenericLambda() const; 
-
-  /// \brief Retrieve the lambda call operator of the closure type
-  /// if this is a closure type.
-  CXXMethodDecl* getLambdaCallOperator() const; 
-
-  /// \brief Retrieve the lambda static invoker, the address of which
-  /// is returned by the conversion operator, and the body of which
-  /// is forwarded to the lambda call operator. 
-  CXXMethodDecl* getLambdaStaticInvoker() const; 
-
-  /// \brief Retrieve the generic lambda's template parameter list.
-  /// Returns null if the class does not represent a lambda or a generic 
-  /// lambda.
-  TemplateParameterList* getGenericLambdaTemplateParameterList() const;
-
-  /// \brief Assign the member call operator of the lambda. 
-  void setLambdaExpr(LambdaExpr *E) {
-    getLambdaData().TheLambdaExpr = E;
-  }
-
-  /// \brief Retrieve the parent lambda expression.
-  LambdaExpr* getLambdaExpr() const {
-    return isLambda() ? getLambdaData().TheLambdaExpr : 0;
-  }
-
-
   /// \brief For a closure type, retrieve the mapping from captured
   /// variables and \c this to the non-static data members that store the
   /// values or references of the captures.
index 39112b3..1dfa3b5 100644 (file)
@@ -1604,13 +1604,6 @@ public:
   /// lambda expression. 
   CXXMethodDecl *getCallOperator() const;
 
-  /// \brief If this is a generic lambda expression, retrieve the template 
-  /// parameter list associated with it, or else return null. 
-  TemplateParameterList *getTemplateParameterList() const;
-
-  /// \brief Whether this is a generic lambda.
-  bool isGenericLambda() const { return !!getTemplateParameterList(); }
-
   /// \brief Retrieve the body of the lambda.
   CompoundStmt *getBody() const;
 
index 246d3e1..6e2246b 100644 (file)
@@ -3614,11 +3614,10 @@ public:
 /// is no deduced type and an auto type is canonical. In the latter case, it is
 /// also a dependent type.
 class AutoType : public Type, public llvm::FoldingSetNode {
-  AutoType(QualType DeducedType, bool IsDecltypeAuto, 
-           bool IsDependent, bool IsParameterPack)
+  AutoType(QualType DeducedType, bool IsDecltypeAuto, bool IsDependent)
     : Type(Auto, DeducedType.isNull() ? QualType(this, 0) : DeducedType,
            /*Dependent=*/IsDependent, /*InstantiationDependent=*/IsDependent,
-           /*VariablyModified=*/false, /*ContainsParameterPack=*/IsParameterPack) {
+           /*VariablyModified=*/false, /*ContainsParameterPack=*/false) {
     assert((DeducedType.isNull() || !IsDependent) &&
            "auto deduced to dependent type");
     AutoTypeBits.IsDecltypeAuto = IsDecltypeAuto;
@@ -3642,17 +3641,14 @@ public:
   }
 
   void Profile(llvm::FoldingSetNodeID &ID) {
-    Profile(ID, getDeducedType(), isDecltypeAuto(), 
-                   isDependentType(), containsUnexpandedParameterPack());
+    Profile(ID, getDeducedType(), isDecltypeAuto(), isDependentType());
   }
 
   static void Profile(llvm::FoldingSetNodeID &ID, QualType Deduced,
-                      bool IsDecltypeAuto, bool IsDependent, 
-                      bool IsParameterPack) {
+                      bool IsDecltypeAuto, bool IsDependent) {
     ID.AddPointer(Deduced.getAsOpaquePtr());
     ID.AddBoolean(IsDecltypeAuto);
     ID.AddBoolean(IsDependent);
-    ID.AddBoolean(IsParameterPack);
   }
 
   static bool classof(const Type *T) {
index 7a0431b..dd0c540 100644 (file)
@@ -5050,10 +5050,6 @@ let CategoryName = "Lambda Issue" in {
     "cannot deduce type for lambda capture %0 from initializer list">;
 }
 
-// C++1y Generic Lambdas
-def err_glambda_not_fully_implemented : Error<
-  "unimplemented generic lambda feature: %0">;
-    
 def err_return_in_captured_stmt : Error<
   "cannot return from %0">;
 def err_capture_block_variable : Error<
index dfb7932..5924a15 100644 (file)
@@ -1502,7 +1502,6 @@ public:
     ObjCCatchContext,    // Objective-C catch exception-declaration
     BlockLiteralContext, // Block literal declarator.
     LambdaExprContext,   // Lambda-expression declarator.
-    LambdaExprParameterContext, // Lambda-expression parameter declarator.
     ConversionIdContext, // C++ conversion-type-id.
     TrailingReturnContext, // C++11 trailing-type-specifier.
     TemplateTypeArgContext, // Template type argument.
@@ -1578,6 +1577,7 @@ public:
   ~Declarator() {
     clear();
   }
+
   /// getDeclSpec - Return the declaration-specifier that this declarator was
   /// declared with.
   const DeclSpec &getDeclSpec() const { return DS; }
@@ -1606,8 +1606,7 @@ public:
   bool isPrototypeContext() const {
     return (Context == PrototypeContext ||
             Context == ObjCParameterContext ||
-            Context == ObjCResultContext ||
-            Context == LambdaExprParameterContext);
+            Context == ObjCResultContext);
   }
 
   /// \brief Get the source range that spans this declarator.
@@ -1671,7 +1670,6 @@ public:
     case AliasDeclContext:
     case AliasTemplateContext:
     case PrototypeContext:
-    case LambdaExprParameterContext:
     case ObjCParameterContext:
     case ObjCResultContext:
     case TemplateParamContext:
@@ -1700,7 +1698,6 @@ public:
     case ForContext:
     case ConditionContext:
     case PrototypeContext:
-    case LambdaExprParameterContext:
     case TemplateParamContext:
     case CXXCatchContext:
     case ObjCCatchContext:
@@ -1733,7 +1730,6 @@ public:
     case ForContext:
     case ConditionContext:
     case PrototypeContext:
-    case LambdaExprParameterContext:
     case TemplateParamContext:
     case CXXCatchContext:
     case ObjCCatchContext:
@@ -1786,7 +1782,6 @@ public:
     case KNRTypeListContext:
     case MemberContext:
     case PrototypeContext:
-    case LambdaExprParameterContext:
     case ObjCParameterContext:
     case ObjCResultContext:
     case TemplateParamContext:
@@ -1973,7 +1968,6 @@ public:
     case AliasDeclContext:
     case AliasTemplateContext:
     case PrototypeContext:
-    case LambdaExprParameterContext:
     case ObjCParameterContext:
     case ObjCResultContext:
     case TemplateParamContext:
index d3f866b..86725e1 100644 (file)
@@ -35,8 +35,6 @@ class LabelDecl;
 class ReturnStmt;
 class Scope;
 class SwitchStmt;
-class TemplateTypeParmDecl;
-class TemplateParameterList;
 class VarDecl;
 class DeclRefExpr;
 class ObjCIvarRefExpr;
@@ -615,27 +613,12 @@ public:
   /// \brief Offsets into the ArrayIndexVars array at which each capture starts
   /// its list of array index variables.
   SmallVector<unsigned, 4> ArrayIndexStarts;
-  
-  /// \brief If this is a generic lambda, use this as the depth of 
-  /// each 'auto' parameter, during initial AST construction.
-  unsigned AutoTemplateParameterDepth;
-
-  // If this is a generic lambda, store the list of the auto 
-  // parameters converted into TemplateTypeParmDecls into a vector
-  // that can be used to construct the generic lambda's template
-  // parameter list, during initial AST construction.
-  /// \brief Store the list of the auto parameters for a generic lambda.
-  SmallVector<TemplateTypeParmDecl*, 4> AutoTemplateParams;
-
-  // If this is a generic lambda, store its template parameter list.
-  TemplateParameterList *GLTemplateParameterList;
-  
-  LambdaScopeInfo(DiagnosticsEngine &Diag)
-    : CapturingScopeInfo(Diag, ImpCap_None), Lambda(0),
-      CallOperator(0), NumExplicitCaptures(0), Mutable(false),
-      ExprNeedsCleanups(false), ContainsUnexpandedParameterPack(false),
-      AutoTemplateParameterDepth(0),
-      GLTemplateParameterList(0)
+
+  LambdaScopeInfo(DiagnosticsEngine &Diag, CXXRecordDecl *Lambda,
+                  CXXMethodDecl *CallOperator)
+    : CapturingScopeInfo(Diag, ImpCap_None), Lambda(Lambda),
+      CallOperator(CallOperator), NumExplicitCaptures(0), Mutable(false),
+      ExprNeedsCleanups(false), ContainsUnexpandedParameterPack(false)
   {
     Kind = SK_Lambda;
   }
@@ -648,10 +631,8 @@ public:
   }
 
   static bool classof(const FunctionScopeInfo *FSI) {
-    return FSI->Kind == SK_Lambda; 
+    return FSI->Kind == SK_Lambda;
   }
-
-
 };
 
 
index 70d4ce4..749c64d 100644 (file)
@@ -969,13 +969,7 @@ public:
 
   void PushFunctionScope();
   void PushBlockScope(Scope *BlockScope, BlockDecl *Block);
-  void PushLambdaScope();
-  
-  // This is used to inform Sema what the current TemplateParameterDepth
-  // is during Parsing.  Currently it is used to pass on the depth
-  // when parsing generic lambda 'auto' parameters.
-  void RecordParsingTemplateParameterDepth(unsigned Depth);
-  
+  void PushLambdaScope(CXXRecordDecl *Lambda, CXXMethodDecl *CallOperator);
   void PushCapturedRegionScope(Scope *RegionScope, CapturedDecl *CD,
                                RecordDecl *RD,
                                CapturedRegionKind K);
@@ -1002,12 +996,9 @@ public:
   /// \brief Retrieve the current block, if any.
   sema::BlockScopeInfo *getCurBlock();
 
-  /// \brief Retrieve the current lambda scope info, if any.
+  /// \brief Retrieve the current lambda expression, if any.
   sema::LambdaScopeInfo *getCurLambda();
 
-  /// \brief Retrieve the current generic lambda info, if any.
-  sema::LambdaScopeInfo *getCurGenericLambda();
-
   /// \brief Retrieve the current captured region, if any.
   sema::CapturedRegionScopeInfo *getCurCapturedRegion();
 
@@ -4410,10 +4401,6 @@ public:
   /// initializer for the declaration 'Dcl'.
   void ActOnCXXExitDeclInitializer(Scope *S, Decl *Dcl);
 
-  /// \brief Invoked when an auto parameter is parsed
-  /// in a lambda's parameter declaration clause.
-  ParmVarDecl *ActOnLambdaAutoParameter(ParmVarDecl *P);
-
   /// \brief Create a new lambda closure type.
   CXXRecordDecl *createLambdaClosureType(SourceRange IntroducerRange,
                                          TypeSourceInfo *Info,
@@ -4426,15 +4413,14 @@ public:
                                        SourceLocation EndLoc,
                                        ArrayRef<ParmVarDecl *> Params);
 
-  /// \brief Endow the lambda scope info with the relevant properties.
-  void buildLambdaScope(sema::LambdaScopeInfo *LSI, 
-                        CXXMethodDecl *CallOperator,
-                        SourceRange IntroducerRange,
-                        LambdaCaptureDefault CaptureDefault,
-                        SourceLocation CaptureDefaultLoc,
-                        bool ExplicitParams,
-                        bool ExplicitResultType,
-                        bool Mutable);
+  /// \brief Introduce the scope for a lambda expression.
+  sema::LambdaScopeInfo *enterLambdaScope(CXXMethodDecl *CallOperator,
+                                          SourceRange IntroducerRange,
+                                          LambdaCaptureDefault CaptureDefault,
+                                          SourceLocation CaptureDefaultLoc,
+                                          bool ExplicitParams,
+                                          bool ExplicitResultType,
+                                          bool Mutable);
 
   /// \brief Check and build an init-capture with the specified name and
   /// initializer.
@@ -5819,12 +5805,6 @@ public:
                           sema::TemplateDeductionInfo &Info,
                           bool InOverloadResolution = false);
 
-  /// \brief Substitute Replacement for \p auto in \p TypeWithAuto
-  QualType SubstAutoType(QualType TypeWithAuto, QualType Replacement);
-  /// \brief Substitute Replacement for auto in TypeWithAuto
-  TypeSourceInfo* SubstAutoTypeSourceInfo(TypeSourceInfo *TypeWithAuto, 
-                                          QualType Replacement);
-
   /// \brief Result type of DeduceAutoType.
   enum DeduceAutoResult {
     DAR_Succeeded,
@@ -5836,6 +5816,7 @@ public:
                                   QualType &Result);
   DeduceAutoResult DeduceAutoType(TypeLoc AutoTypeLoc, Expr *&Initializer,
                                   QualType &Result);
+  QualType SubstAutoType(QualType TypeWithAuto, QualType Replacement);
   void DiagnoseAutoDeductionFailure(VarDecl *VDecl, Expr *Init);
   bool DeduceReturnType(FunctionDecl *FD, SourceLocation Loc,
                         bool Diagnose = true);
diff --git a/clang/include/clang/Sema/SemaLambda.h b/clang/include/clang/Sema/SemaLambda.h
deleted file mode 100644 (file)
index e01dc35..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-//===--- SemaLambda.h - Lambda Helper Functions --------------*- C++ -*-===//\r
-//\r
-//                     The LLVM Compiler Infrastructure\r
-//\r
-// This file is distributed under the University of Illinois Open Source\r
-// License. See LICENSE.TXT for details.\r
-//\r
-//===----------------------------------------------------------------------===//\r
-///\r
-/// \file\r
-/// \brief This file provides some common utility functions for processing\r
-/// Lambdas.\r
-///\r
-//===----------------------------------------------------------------------===//\r
-\r
-#ifndef LLVM_CLANG_SEMA_LAMBDA_H\r
-#define LLVM_CLANG_SEMA_LAMBDA_H\r
-\r
-#include "clang/AST/DeclCXX.h"\r
-#include "clang/AST/DeclTemplate.h"\r
-#include "clang/Sema/ScopeInfo.h"\r
-\r
-namespace clang {\r
-static inline const char *getLambdaStaticInvokerName() {\r
-  return "__invoke";\r
-}\r
-static inline bool isGenericLambdaCallOperatorSpecialization(CXXMethodDecl *MD) {\r
-  if (MD) {\r
-    CXXRecordDecl *LambdaClass = MD->getParent();\r
-    if (LambdaClass && LambdaClass->isGenericLambda()) {\r
-      return LambdaClass->getLambdaCallOperator() \r
-                  == MD->getTemplateInstantiationPattern();\r
-    }\r
-  }\r
-  return false;\r
-}\r
-\r
-static inline bool isGenericLambdaCallOperatorSpecialization(Decl *D) {\r
-  return isGenericLambdaCallOperatorSpecialization(\r
-                                dyn_cast<CXXMethodDecl>(D));\r
-}\r
-} // clang\r
-\r
-#endif // LLVM_CLANG_SEMA_LAMBDA_H\r
index b1b52fb..29ddb37 100644 (file)
@@ -3649,24 +3649,20 @@ QualType ASTContext::getUnaryTransformType(QualType BaseType,
 /// deduced to the given type, or to the canonical undeduced 'auto' type, or the
 /// canonical deduced-but-dependent 'auto' type.
 QualType ASTContext::getAutoType(QualType DeducedType, bool IsDecltypeAuto,
-                             bool IsDependent, bool IsParameterPack) const {
-  if (DeducedType.isNull() && !IsDecltypeAuto && !IsDependent && 
-                              !IsParameterPack)
+                                 bool IsDependent) const {
+  if (DeducedType.isNull() && !IsDecltypeAuto && !IsDependent)
     return getAutoDeductType();
-  assert(!IsParameterPack || DeducedType.isNull() 
-           && "Auto parameter pack: auto ... a should always be undeduced!");
+
   // Look in the folding set for an existing type.
   void *InsertPos = 0;
   llvm::FoldingSetNodeID ID;
-  AutoType::Profile(ID, DeducedType, IsDecltypeAuto, IsDependent, 
-     IsParameterPack);
+  AutoType::Profile(ID, DeducedType, IsDecltypeAuto, IsDependent);
   if (AutoType *AT = AutoTypes.FindNodeOrInsertPos(ID, InsertPos))
     return QualType(AT, 0);
 
   AutoType *AT = new (*this, TypeAlignment) AutoType(DeducedType,
                                                      IsDecltypeAuto,
-                                                     IsDependent, 
-                                                     IsParameterPack);
+                                                     IsDependent);
   Types.push_back(AT);
   if (InsertPos)
     AutoTypes.InsertNode(AT, InsertPos);
@@ -3706,8 +3702,7 @@ QualType ASTContext::getAutoDeductType() const {
   if (AutoDeductTy.isNull())
     AutoDeductTy = QualType(
       new (*this, TypeAlignment) AutoType(QualType(), /*decltype(auto)*/false,
-                                          /*dependent*/false, 
-                                          /*IsParameterPack*/false),
+                                          /*dependent*/false),
       0);
   return AutoDeductTy;
 }
index f03b66d..9221727 100644 (file)
@@ -1709,9 +1709,7 @@ QualType ASTNodeImporter::VisitAutoType(const AutoType *T) {
       return QualType();
   }
   
-  return Importer.getToContext().getAutoType(ToDeduced, T->isDecltypeAuto(), 
-                                             /*IsDependent*/false,
-                                      T->containsUnexpandedParameterPack());
+  return Importer.getToContext().getAutoType(ToDeduced, T->isDecltypeAuto());
 }
 
 QualType ASTNodeImporter::VisitRecordType(const RecordType *T) {
index b50aa93..ccd8220 100644 (file)
@@ -20,7 +20,6 @@
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/TypeLoc.h"
 #include "clang/Basic/IdentifierTable.h"
-#include "clang/Sema/SemaLambda.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallPtrSet.h"
 using namespace clang;
@@ -931,40 +930,6 @@ bool CXXRecordDecl::isCLike() const {
   return isPOD() && data().HasOnlyCMembers;
 }
 
-bool CXXRecordDecl::isGenericLambda() const { 
-  return isLambda() && 
-      getLambdaCallOperator()->getDescribedFunctionTemplate(); 
-}
-
-CXXMethodDecl* CXXRecordDecl::getLambdaCallOperator() const {
-  if (!isLambda()) return 0;
-  DeclarationName Name = \r
-    getASTContext().DeclarationNames.getCXXOperatorName(OO_Call);\r
-  DeclContext::lookup_const_result Calls = lookup(Name);
-\r
-  assert(!Calls.empty() && "Missing lambda call operator!");\r
-  assert(Calls.size() == 1 && "More than one lambda call operator!"); \r
-   \r
-  NamedDecl *CallOp = Calls.front();\r
-  if (FunctionTemplateDecl *CallOpTmpl = \r
-                    dyn_cast<FunctionTemplateDecl>(CallOp)) \r
-    return cast<CXXMethodDecl>(CallOpTmpl->getTemplatedDecl());\r
-  
-  return cast<CXXMethodDecl>(CallOp);
-}
-
-CXXMethodDecl* CXXRecordDecl::getLambdaStaticInvoker() const {
-  if (!isLambda()) return 0;
-  DeclarationName Name = \r
-    &getASTContext().Idents.get(getLambdaStaticInvokerName());\r
-  DeclContext::lookup_const_result Invoker = lookup(Name);
-  if (Invoker.empty()) return 0;\r
-  assert(Invoker.size() == 1 && "More than one static invoker operator!");  \r
-  CXXMethodDecl *Result = cast<CXXMethodDecl>(Invoker.front());  \r
-  return Result;
-
-}
-
 void CXXRecordDecl::getCaptureFields(
        llvm::DenseMap<const VarDecl *, FieldDecl *> &Captures,
        FieldDecl *&ThisCapture) const {
@@ -982,14 +947,6 @@ void CXXRecordDecl::getCaptureFields(
   }
 }
 
-TemplateParameterList* 
-        CXXRecordDecl::getGenericLambdaTemplateParameterList() const {
-  if (!isLambda()) return 0;
-  CXXMethodDecl *CallOp = getLambdaCallOperator();     
-  if (FunctionTemplateDecl *Tmpl = CallOp->getDescribedFunctionTemplate())
-    return Tmpl->getTemplateParameters();
-  return 0;
-}
 
 static CanQualType GetConversionType(ASTContext &Context, NamedDecl *Conv) {
   QualType T;
@@ -1536,7 +1493,7 @@ bool CXXMethodDecl::hasInlineBody() const {
 
 bool CXXMethodDecl::isLambdaStaticInvoker() const {
   return getParent()->isLambda() && 
-         getParent()->getLambdaStaticInvoker() == this;
+         getIdentifier() && getIdentifier()->getName() == "__invoke";
 }
 
 
index 6848534..b76bc2f 100644 (file)
@@ -1027,13 +1027,13 @@ CXXRecordDecl *LambdaExpr::getLambdaClass() const {
 
 CXXMethodDecl *LambdaExpr::getCallOperator() const {
   CXXRecordDecl *Record = getLambdaClass();
-  return Record->getLambdaCallOperator();  
-}
-
-TemplateParameterList *LambdaExpr::getTemplateParameterList() const {
-  CXXRecordDecl *Record = getLambdaClass();
-  return Record->getGenericLambdaTemplateParameterList();
-
+  DeclarationName Name
+    = Record->getASTContext().DeclarationNames.getCXXOperatorName(OO_Call);
+  DeclContext::lookup_result Calls = Record->lookup(Name);
+  assert(!Calls.empty() && "Missing lambda call operator!");
+  assert(Calls.size() == 1 && "More than one lambda call operator!");
+  CXXMethodDecl *Result = cast<CXXMethodDecl>(Calls.front());
+  return Result;
 }
 
 CompoundStmt *LambdaExpr::getBody() const {
index 6b639db..ef423eb 100644 (file)
@@ -589,10 +589,6 @@ namespace {
     AutoType *VisitAttributedType(const AttributedType *T) {
       return Visit(T->getModifiedType());
     }
-    AutoType *VisitPackExpansionType(const PackExpansionType *T) {
-      return Visit(T->getPattern());
-    }
-
   };
 }
 
index c271d7c..da8db17 100644 (file)
@@ -700,7 +700,7 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn,
     EmitLambdaToBlockPointerBody(Args);
   } else if (isa<CXXMethodDecl>(FD) &&
              cast<CXXMethodDecl>(FD)->isLambdaStaticInvoker()) {
-    // The lambda static invoker function is special, because it forwards or
+    // The lambda "__invoke" function is special, because it forwards or
     // clones the body of the function call operator (but is actually static).
     EmitLambdaStaticInvokeFunction(cast<CXXMethodDecl>(FD));
   } else if (FD->isDefaulted() && isa<CXXMethodDecl>(FD) &&
index 4c4ce87..392535a 100644 (file)
@@ -4670,7 +4670,6 @@ void Parser::ParseDirectDeclarator(Declarator &D) {
     //   as part of the parameter-declaration-clause.
     if (Tok.is(tok::ellipsis) && D.getCXXScopeSpec().isEmpty() &&
         !((D.getContext() == Declarator::PrototypeContext ||
-           D.getContext() == Declarator::LambdaExprParameterContext ||
            D.getContext() == Declarator::BlockLiteralContext) &&
           NextToken().is(tok::r_paren) &&
           !D.hasGroupingParens() &&
@@ -4989,6 +4988,7 @@ void Parser::ParseFunctionDeclarator(Declarator &D,
   TypeResult TrailingReturnType;
 
   Actions.ActOnStartFunctionDeclarator();
+
   /* LocalEndLoc is the end location for the local FunctionTypeLoc.
      EndLoc is the end location for the function declarator.
      They differ for trailing return types. */
@@ -5009,8 +5009,7 @@ void Parser::ParseFunctionDeclarator(Declarator &D,
     EndLoc = RParenLoc;
   } else {
     if (Tok.isNot(tok::r_paren))
-      ParseParameterDeclarationClause(D, FirstArgAttrs, ParamInfo, 
-                                      EllipsisLoc);
+      ParseParameterDeclarationClause(D, FirstArgAttrs, ParamInfo, EllipsisLoc);
     else if (RequiresArg)
       Diag(Tok, diag::err_argument_required_after_attribute);
 
@@ -5241,6 +5240,7 @@ void Parser::ParseParameterDeclarationClause(
        ParsedAttributes &FirstArgAttrs,
        SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo,
        SourceLocation &EllipsisLoc) {
+
   while (1) {
     if (Tok.is(tok::ellipsis)) {
       // FIXME: Issue a diagnostic if we parsed an attribute-specifier-seq
@@ -5270,21 +5270,16 @@ void Parser::ParseParameterDeclarationClause(
 
     ParseDeclarationSpecifiers(DS);
 
-
-    // Parse the declarator.  This is "PrototypeContext" or 
-    // "LambdaExprParameterContext", because we must accept either 
-    // 'declarator' or 'abstract-declarator' here.
-    Declarator ParmDeclarator(DS, 
-              D.getContext() == Declarator::LambdaExprContext ?
-                                  Declarator::LambdaExprParameterContext : 
-                                                Declarator::PrototypeContext);
-    ParseDeclarator(ParmDeclarator);
+    // Parse the declarator.  This is "PrototypeContext", because we must
+    // accept either 'declarator' or 'abstract-declarator' here.
+    Declarator ParmDecl(DS, Declarator::PrototypeContext);
+    ParseDeclarator(ParmDecl);
 
     // Parse GNU attributes, if present.
-    MaybeParseGNUAttributes(ParmDeclarator);
+    MaybeParseGNUAttributes(ParmDecl);
 
     // Remember this parsed parameter in ParamInfo.
-    IdentifierInfo *ParmII = ParmDeclarator.getIdentifier();
+    IdentifierInfo *ParmII = ParmDecl.getIdentifier();
 
     // DefArgToks is used when the parsing of default arguments needs
     // to be delayed.
@@ -5292,8 +5287,8 @@ void Parser::ParseParameterDeclarationClause(
 
     // If no parameter was specified, verify that *something* was specified,
     // otherwise we have a missing type and identifier.
-    if (DS.isEmpty() && ParmDeclarator.getIdentifier() == 0 &&
-        ParmDeclarator.getNumTypeObjects() == 0) {
+    if (DS.isEmpty() && ParmDecl.getIdentifier() == 0 &&
+        ParmDecl.getNumTypeObjects() == 0) {
       // Completely missing, emit error.
       Diag(DSStart, diag::err_missing_param);
     } else {
@@ -5302,8 +5297,8 @@ void Parser::ParseParameterDeclarationClause(
 
       // Inform the actions module about the parameter declarator, so it gets
       // added to the current scope.
-      Decl *Param = Actions.ActOnParamDeclarator(getCurScope(), 
-                                                       ParmDeclarator);
+      Decl *Param = Actions.ActOnParamDeclarator(getCurScope(), ParmDecl);
+
       // Parse the default argument, if any. We parse the default
       // arguments in all dialects; the semantic analysis in
       // ActOnParamDefaultArgument will reject the default argument in
@@ -5364,8 +5359,8 @@ void Parser::ParseParameterDeclarationClause(
       }
 
       ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
-                                          ParmDeclarator.getIdentifierLoc(), 
-                                          Param, DefArgToks));
+                                          ParmDecl.getIdentifierLoc(), Param,
+                                          DefArgToks));
     }
 
     // If the next token is a comma, consume it and keep reading arguments.
index 1ab7047..9ac6d43 100644 (file)
@@ -20,7 +20,6 @@
 #include "clang/Sema/ParsedTemplate.h"
 #include "clang/Sema/Scope.h"
 #include "llvm/Support/ErrorHandling.h"
-#include "clang/AST/DeclTemplate.h"
 
 using namespace clang;
 
@@ -909,16 +908,12 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
   PrettyStackTraceLoc CrashInfo(PP.getSourceManager(), LambdaBeginLoc,
                                 "lambda expression parsing");
 
-
   // FIXME: Call into Actions to add any init-capture declarations to the
   // scope while parsing the lambda-declarator and compound-statement.
 
   // Parse lambda-declarator[opt].
   DeclSpec DS(AttrFactory);
   Declarator D(DS, Declarator::LambdaExprContext);
-  TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);
-  Actions.PushLambdaScope();    
 
   if (Tok.is(tok::l_paren)) {
     ParseScope PrototypeScope(this,
@@ -936,17 +931,9 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
     SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
     SourceLocation EllipsisLoc;
 
-    
-    if (Tok.isNot(tok::r_paren)) {
-      sema::LambdaScopeInfo *LSI = Actions.getCurLambda(); 
-      if (getLangOpts().CPlusPlus1y)
-        Actions.RecordParsingTemplateParameterDepth(TemplateParameterDepth);
+    if (Tok.isNot(tok::r_paren))
       ParseParameterDeclarationClause(D, Attr, ParamInfo, EllipsisLoc);
-      // For a generic lambda, each 'auto' within the parameter declaration 
-      // clause creates a template type parameter, so increment the depth.
-      if (getLangOpts().CPlusPlus1y && Actions.getCurGenericLambda()) 
-        ++CurTemplateDepthTracker;
-    }
+
     T.consumeClose();
     SourceLocation RParenLoc = T.getCloseLocation();
     DeclEndLoc = RParenLoc;
index 6ee97d4..866572c 100644 (file)
@@ -1175,6 +1175,7 @@ void Parser::ParseKNRParamDeclarations(Declarator &D) {
       // Ask the actions module to compute the type for this declarator.
       Decl *Param =
         Actions.ActOnParamDeclarator(getCurScope(), ParmDeclarator);
+
       if (Param &&
           // A missing identifier has already been diagnosed.
           ParmDeclarator.getIdentifier()) {
index aab0389..6cc596c 100644 (file)
@@ -1007,17 +1007,10 @@ void Sema::PushBlockScope(Scope *BlockScope, BlockDecl *Block) {
                                               BlockScope, Block));
 }
 
-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::PushLambdaScope(CXXRecordDecl *Lambda,
+                           CXXMethodDecl *CallOperator) {
+  FunctionScopes.push_back(new LambdaScopeInfo(getDiagnostics(), Lambda,
+                                               CallOperator));
 }
 
 void Sema::PopFunctionScopeInfo(const AnalysisBasedWarnings::Policy *WP,
@@ -1073,16 +1066,6 @@ LambdaScopeInfo *Sema::getCurLambda() {
 
   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 &&
index d5d8904..80863e3 100644 (file)
@@ -35,7 +35,6 @@
 #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"
@@ -8910,7 +8909,6 @@ Decl *Sema::ActOnParamDeclarator(Scope *S, Declarator &D) {
   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) {
@@ -9017,14 +9015,6 @@ Decl *Sema::ActOnParamDeclarator(Scope *S, Declarator &D) {
   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;
 }
 
@@ -9278,38 +9268,9 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D) {
     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();
-
-    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();
+
+  // Enter a new function scope
+  PushFunctionScope();
 
   // See if this is a redefinition.
   if (!FD->isLateTemplateParsed())
index bde9c15..6ebfb57 100644 (file)
@@ -32,7 +32,6 @@
 #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"
@@ -10016,27 +10015,29 @@ void Sema::DefineImplicitLambdaToFunctionPointerConversion(
        SourceLocation CurrentLocation,
        CXXConversionDecl *Conv) 
 {
-  CXXRecordDecl *LambdaClass = Conv->getParent();
+  CXXRecordDecl *Lambda = Conv->getParent();
   
   // Make sure that the lambda call operator is marked used.
-  markLambdaCallOperatorUsed(*this, LambdaClass);
+  markLambdaCallOperatorUsed(*this, Lambda);
   
   Conv->setUsed();
   
   SynthesizedFunctionScope Scope(*this, Conv);
   DiagnosticErrorTrap Trap(Diags);
   
-  CXXMethodDecl *Invoke = LambdaClass->getLambdaStaticInvoker();
-
+  // Return the address of the __invoke function.
+  DeclarationName InvokeName = &Context.Idents.get("__invoke");
+  CXXMethodDecl *Invoke 
+    = cast<CXXMethodDecl>(Lambda->lookup(InvokeName).front());
   Expr *FunctionRef = BuildDeclRefExpr(Invoke, Invoke->getType(),
                                        VK_LValue, Conv->getLocation()).take();
-  assert(FunctionRef && "Can't refer to lambda static invoker function?");
+  assert(FunctionRef && "Can't refer to __invoke 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();
index bed71a6..ae3a938 100644 (file)
@@ -14,7 +14,6 @@
 #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"
@@ -121,69 +120,11 @@ Sema::getCurrentMangleNumberContext(const DeclContext *DC,
   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
@@ -211,17 +152,6 @@ CXXMethodDecl *Sema::startLambdaDefinition(CXXRecordDecl *Class,
   // 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()) {
@@ -247,16 +177,15 @@ CXXMethodDecl *Sema::startLambdaDefinition(CXXRecordDecl *Class,
   return Method;
 }
 
-void Sema::buildLambdaScope(LambdaScopeInfo *LSI,
-                                        CXXMethodDecl *CallOperator,
+LambdaScopeInfo *Sema::enterLambdaScope(CXXMethodDecl *CallOperator,
                                         SourceRange IntroducerRange,
                                         LambdaCaptureDefault CaptureDefault,
                                         SourceLocation CaptureDefaultLoc,
                                         bool ExplicitParams,
                                         bool ExplicitResultType,
                                         bool Mutable) {
-  LSI->CallOperator = CallOperator;
-  LSI->Lambda = CallOperator->getParent();
+  PushLambdaScope(CallOperator->getParent(), CallOperator);
+  LambdaScopeInfo *LSI = getCurLambda();
   if (CaptureDefault == LCD_ByCopy)
     LSI->ImpCaptureStyle = LambdaScopeInfo::ImpCap_LambdaByval;
   else if (CaptureDefault == LCD_ByRef)
@@ -279,6 +208,8 @@ void Sema::buildLambdaScope(LambdaScopeInfo *LSI,
   } else {
     LSI->HasImplicitReturnType = true;
   }
+
+  return LSI;
 }
 
 void Sema::finishLambdaExplicitCaptures(LambdaScopeInfo *LSI) {
@@ -427,7 +358,7 @@ static void adjustBlockReturnsToEnum(Sema &S, ArrayRef<ReturnStmt*> returns,
 }
 
 void Sema::deduceClosureReturnType(CapturingScopeInfo &CSI) {
-  assert(CSI.HasImplicitReturnType || CSI.ReturnType->isUndeducedType());
+  assert(CSI.HasImplicitReturnType);
 
   // C++ Core Issue #975, proposed resolution:
   //   If a lambda-expression does not include a trailing-return-type,
@@ -461,7 +392,7 @@ void Sema::deduceClosureReturnType(CapturingScopeInfo &CSI) {
   // 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() || CSI.ReturnType->isUndeducedType())
+  if (CSI.ReturnType->isDependentType())
     return;
 
   // Try to apply the enum-fuzz rule.
@@ -588,25 +519,15 @@ FieldDecl *Sema::checkInitCapture(SourceLocation Loc, bool ByRef,
 }
 
 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;
-  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())
+  if (Scope *TmplScope = CurScope->getTemplateParamParent())
+    if (!TmplScope->decl_empty())
       KnownDependent = true;
-  }
+  
   // Determine the signature of the call operator.
   TypeSourceInfo *MethodTyInfo;
   bool ExplicitParams = true;
@@ -621,11 +542,7 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
     FunctionProtoType::ExtProtoInfo EPI;
     EPI.HasTrailingReturn = true;
     EPI.TypeQuals |= DeclSpec::TQ_const;
-    // 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,
+    QualType MethodTy = Context.getFunctionType(Context.DependentTy, None,
                                                 EPI);
     MethodTyInfo = Context.getTrivialTypeSourceInfo(MethodTy);
     ExplicitParams = false;
@@ -643,15 +560,14 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
     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.
@@ -672,6 +588,7 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
 
   CXXMethodDecl *Method = startLambdaDefinition(Class, Intro.Range,
                                                 MethodTyInfo, EndLoc, Params);
+  
   if (ExplicitParams)
     CheckCXXDefaultArguments(Method);
   
@@ -681,8 +598,9 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
   // Introduce the function call operator as the current declaration context.
   PushDeclContext(CurScope, Method);
     
-  // Build the lambda scope.
-  buildLambdaScope(LSI, Method,
+  // Introduce the lambda scope.
+  LambdaScopeInfo *LSI
+    = enterLambdaScope(Method,
                        Intro.Range,
                        Intro.Default, Intro.DefaultLoc,
                        ExplicitParams,
@@ -894,8 +812,6 @@ static void addFunctionPointerConversion(Sema &S,
                                          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>(); 
@@ -933,9 +849,10 @@ static void addFunctionPointerConversion(Sema &S,
   Conversion->setAccess(AS_public);
   Conversion->setImplicit(true);
   Class->addDecl(Conversion);
-  // 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());
+  
+  // Add a non-static member function "__invoke" that will be the result of
+  // the conversion.
+  Name = &S.Context.Idents.get("__invoke");
   CXXMethodDecl *Invoke
     = CXXMethodDecl::Create(S.Context, Class, Loc, 
                             DeclarationNameInfo(Name, Loc), FunctionTy, 
@@ -1083,11 +1000,8 @@ ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body,
     //   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 && !getLangOpts().CPlusPlus1y) {
+    if (LSI->HasImplicitReturnType) {
       deduceClosureReturnType(*LSI);
 
       //   - if there are no return statements in the
@@ -1105,18 +1019,13 @@ ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body,
           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);
-    Decl *TemplateOrNonTemplateCallOperatorDecl = 
-      !CallOperator->getDescribedFunctionTemplate() ? cast<Decl>(CallOperator)
-        : CallOperator->getDescribedFunctionTemplate();
-
-    TemplateOrNonTemplateCallOperatorDecl->setLexicalDeclContext(Class);
-    Class->addDecl(TemplateOrNonTemplateCallOperatorDecl);
-
+    Class->addDecl(CallOperator);
     PopExpressionEvaluationContext();
 
     // C++11 [expr.prim.lambda]p6:
@@ -1156,7 +1065,7 @@ ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body,
                                           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).
@@ -1176,15 +1085,7 @@ ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body,
       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);
 }
 
index 33dbf14..06d1f0b 100644 (file)
@@ -8670,10 +8670,6 @@ void DiagnoseBadDeduction(Sema &S, Decl *Templated,
         }
       }
     }
-    // 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;
index c53b31a..8f90746 100644 (file)
@@ -2487,31 +2487,12 @@ Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
   // [expr.prim.lambda]p4 in C++11; block literals follow the same rules.
   CapturingScopeInfo *CurCap = cast<CapturingScopeInfo>(getCurFunction());
   QualType FnRetType = CurCap->ReturnType;
-  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)) {
+
+  // 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.
     if (RetValExp && !isa<InitListExpr>(RetValExp)) {
       ExprResult Result = DefaultFunctionArrayLvalueConversion(RetValExp);
       if (Result.isInvalid())
@@ -2519,7 +2500,13 @@ Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
       RetValExp = Result.take();
 
       if (!CurContext->isDependentContext()) {
-        FnRetType = RetValExp->getType();       
+        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();
       } else
         FnRetType = CurCap->ReturnType = Context.DependentTy;
     } else {
@@ -2530,6 +2517,7 @@ Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
         Diag(ReturnLoc, diag::err_lambda_return_init_list)
           << RetValExp->getSourceRange();
       }
+
       FnRetType = Context.VoidTy;
     }
 
@@ -2538,8 +2526,7 @@ Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
     if (CurCap->ReturnType.isNull())
       CurCap->ReturnType = FnRetType;
   } else if (AutoType *AT =
-                 (FnRetType.isNull() || !LambdaSI) ? 0 
-                      : FnRetType->getContainedAutoType()) {
+                 FnRetType.isNull() ? 0 : FnRetType->getContainedAutoType()) {
     // In C++1y, the return type may involve 'auto'.
     FunctionDecl *FD = cast<LambdaScopeInfo>(CurCap)->CallOperator;
     if (CurContext->isDependentContext()) {
@@ -2547,7 +2534,7 @@ Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
       //   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;
+      CurCap->ReturnType = FnRetType = Context.DependentTy;
     } else if (DeduceFunctionTypeFromReturnExpr(FD, ReturnLoc, RetValExp, AT)) {
       FD->setInvalidDecl();
       return StmtError();
@@ -2577,7 +2564,7 @@ Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
   // 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() || FnRetType->isUndeducedType()) {
+  if (FnRetType->isDependentType()) {
     // Delay processing for now.  TODO: there are lots of dependent
     // types we can conclusively prove aren't void.
   } else if (FnRetType->isVoidType()) {
@@ -2637,6 +2624,7 @@ Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
 
   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,
@@ -2646,6 +2634,7 @@ bool Sema::DeduceFunctionTypeFromReturnExpr(FunctionDecl *FD,
   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.
@@ -2703,18 +2692,9 @@ bool Sema::DeduceFunctionTypeFromReturnExpr(FunctionDecl *FD,
     AutoType *NewAT = Deduced->getContainedAutoType();
     if (!FD->isDependentContext() &&
         !Context.hasSameType(AT->getDeducedType(), NewAT->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();
-      }
+      Diag(ReturnLoc, diag::err_auto_fn_different_deductions)
+        << (AT->isDecltypeAuto() ? 1 : 0)
+        << NewAT->getDeducedType() << AT->getDeducedType();
       return true;
     }
   } else if (!FD->isInvalidDecl()) {
@@ -2730,8 +2710,10 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
   // 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()) {
index 813f71d..c8669ae 100644 (file)
@@ -3766,8 +3766,7 @@ namespace {
         QualType Result =
           SemaRef.Context.getAutoType(Dependent ? QualType() : Replacement,
                                       TL.getTypePtr()->isDecltypeAuto(),
-                                      Dependent, TL.getTypePtr()->
-                                        containsUnexpandedParameterPack());
+                                      Dependent);
         AutoTypeLoc NewTL = TLB.push<AutoTypeLoc>(Result);
         NewTL.setNameLoc(TL.getNameLoc());
         return Result;
@@ -3908,16 +3907,8 @@ Sema::DeduceAutoType(TypeLoc Type, Expr *&Init, QualType &Result) {
   return DAR_Succeeded;
 }
 
-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);
+QualType Sema::SubstAutoType(QualType Type, QualType Deduced) {
+  return SubstituteAutoTransform(*this, Deduced).TransformType(Type);
 }
 
 void Sema::DiagnoseAutoDeductionFailure(VarDecl *VDecl, Expr *Init) {
index 2dabfb2..6998827 100644 (file)
@@ -781,13 +781,7 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {
     // specified with a trailing return type or inferred.
     if (declarator.getContext() == Declarator::LambdaExprContext ||
         isOmittedBlockReturnType(declarator)) {
-      // 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;
+      Result = Context.DependentTy;
       break;
     }
 
@@ -1012,17 +1006,11 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {
 
   case DeclSpec::TST_auto:
     // TypeQuals handled by caller.
-    Result = Context.getAutoType(QualType(), 
-                                /*decltype(auto)*/false, 
-                                /*IsDependent*/   false, 
-                                /*IsParameterPack*/ declarator.hasEllipsis());
+    Result = Context.getAutoType(QualType(), /*decltype(auto)*/false);
     break;
 
   case DeclSpec::TST_decltype_auto:
-    Result = Context.getAutoType(QualType(), 
-                                 /*decltype(auto)*/true, 
-                                 /*IsDependent*/   false, 
-                                 /*IsParameterPack*/ false);
+    Result = Context.getAutoType(QualType(), /*decltype(auto)*/true);
     break;
 
   case DeclSpec::TST_unknown_anytype:
@@ -1569,7 +1557,7 @@ QualType Sema::BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM,
         ASM = ArrayType::Normal;
       }
     } else if (!T->isDependentType() && !T->isVariablyModifiedType() &&
-               !T->isIncompleteType() && !T->isUndeducedType()) {
+               !T->isIncompleteType()) {
       // Is the array too large?
       unsigned ActiveSizeBits
         = ConstantArrayType::getNumAddressingBits(Context, T, ConstVal);
@@ -2109,7 +2097,6 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,
   // 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;
@@ -2122,12 +2109,7 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,
     case Declarator::ObjCParameterContext:
     case Declarator::ObjCResultContext:
     case Declarator::PrototypeContext:
-      Error = 0;  
-      break;
-    case Declarator::LambdaExprParameterContext:
-      if (!(SemaRef.getLangOpts().CPlusPlus1y 
-              && D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto))
-        Error = 0;
+      Error = 0; // Function prototype
       break;
     case Declarator::MemberContext:
       if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static)
@@ -2207,13 +2189,8 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,
       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
@@ -2263,7 +2240,6 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,
       D.setInvalidType(true);
       break;
     case Declarator::PrototypeContext:
-    case Declarator::LambdaExprParameterContext:
     case Declarator::ObjCParameterContext:
     case Declarator::ObjCResultContext:
     case Declarator::KNRTypeListContext:
@@ -2637,11 +2613,8 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
           }
         }
       }
-      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)) {
+
+      if (const AutoType *AT = T->getContainedAutoType()) {
         // We've already diagnosed this for decltype(auto).
         if (!AT->isDecltypeAuto())
           S.Diag(DeclType.Loc, diag::err_illegal_decl_array_of_auto)
@@ -3137,7 +3110,6 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
     //   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
@@ -3156,6 +3128,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
         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
index 164bb89..a627944 100644 (file)
@@ -782,10 +782,7 @@ public:
     // 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.
-    // FIXME: Can we assume the same about IsParameterPack?
-    return SemaRef.Context.getAutoType(Deduced, IsDecltypeAuto, 
-                                       /*IsDependent*/ false, 
-                                       /*IsParameterPack*/ false);
+    return SemaRef.Context.getAutoType(Deduced, IsDecltypeAuto);
   }
 
   /// \brief Build a new template specialization type.
@@ -3496,9 +3493,7 @@ TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB,
         Qs.removeObjCLifetime();
         Deduced = SemaRef.Context.getQualifiedType(Deduced.getUnqualifiedType(),
                                                    Qs);
-        Result = SemaRef.Context.getAutoType(Deduced, AutoTy->isDecltypeAuto(), 
-                                AutoTy->isDependentType(), 
-                                AutoTy->containsUnexpandedParameterPack());
+        Result = SemaRef.Context.getAutoType(Deduced, AutoTy->isDecltypeAuto());
         TLB.TypeWasModifiedSafely(Result);
       } else {
         // Otherwise, complain about the addition of a qualifier to an
@@ -8197,14 +8192,6 @@ TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
 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
@@ -8227,10 +8214,7 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
         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(),
@@ -8265,9 +8249,9 @@ TreeTransform<Derived>::TransformLambdaScope(LambdaExpr *E,
   // Introduce the context of the call operator.
   Sema::ContextRAII SavedContext(getSema(), CallOperator);
 
-  LambdaScopeInfo *const LSI = getSema().getCurLambda();
   // Enter the scope of the lambda.
-  getSema().buildLambdaScope(LSI, CallOperator, E->getIntroducerRange(),
+  sema::LambdaScopeInfo *LSI
+    = getSema().enterLambdaScope(CallOperator, E->getIntroducerRange(),
                                  E->getCaptureDefault(),
                                  E->getCaptureDefaultLoc(),
                                  E->hasExplicitParameters(),
index 5b1a608..462c2d3 100644 (file)
@@ -4740,9 +4740,7 @@ QualType ASTReader::readTypeRecord(unsigned Index) {
     QualType Deduced = readType(*Loc.F, Record, Idx);
     bool IsDecltypeAuto = Record[Idx++];
     bool IsDependent = Deduced.isNull() ? Record[Idx++] : false;
-    bool IsParameterPack = Record[Idx++];
-    return Context.getAutoType(Deduced, IsDecltypeAuto, IsDependent, 
-                                                      IsParameterPack);
+    return Context.getAutoType(Deduced, IsDecltypeAuto, IsDependent);
   }
 
   case TYPE_RECORD: {
index 74e9937..7099d32 100644 (file)
@@ -1201,7 +1201,6 @@ void ASTDeclReader::ReadCXXDefinitionData(
       = (Capture*)Reader.Context.Allocate(sizeof(Capture)*Lambda.NumCaptures);
     Capture *ToCapture = Lambda.Captures;
     Lambda.MethodTyInfo = GetTypeSourceInfo(Record, Idx);
-    Lambda.TheLambdaExpr = cast<LambdaExpr>(Reader.ReadExpr(F));
     for (unsigned I = 0, N = Lambda.NumCaptures; I != N; ++I) {
       SourceLocation Loc = ReadSourceLocation(Record, Idx);
       bool IsImplicit = Record[Idx++];
index 01bc9cb..d848530 100644 (file)
@@ -253,7 +253,6 @@ void ASTTypeWriter::VisitAutoType(const AutoType *T) {
   Record.push_back(T->isDecltypeAuto());
   if (T->getDeducedType().isNull())
     Record.push_back(T->isDependentType());
-  Record.push_back(T->containsUnexpandedParameterPack());
   Code = TYPE_AUTO;
 }
 
@@ -5137,7 +5136,6 @@ void ASTWriter::AddCXXDefinitionData(const CXXRecordDecl *D, RecordDataImpl &Rec
     Record.push_back(Lambda.ManglingNumber);
     AddDeclRef(Lambda.ContextDecl, Record);
     AddTypeSourceInfo(Lambda.MethodTyInfo, Record);
-    AddStmt(Lambda.TheLambdaExpr);
     for (unsigned I = 0, N = Lambda.NumCaptures; I != N; ++I) {
       LambdaExpr::Capture &Capture = Lambda.Captures[I];
       AddSourceLocation(Capture.getLocation(), Record);
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-generic-lambda-1y.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-generic-lambda-1y.cpp
deleted file mode 100644 (file)
index 29044f4..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++1y -DCXX1Y
-
-//FIXME: These tests were written when return type deduction had not been implemented
-// for generic lambdas, hence
-template<class T> T id(T t);
-template<class ... Ts> int vfoo(Ts&& ... ts);
-auto GL1 = [](auto a, int i) -> int { return id(a); };
-
-auto GL2 = [](auto ... As) -> int { return vfoo(As...); };
-auto GL3 = [](int i, char c, auto* ... As) -> int { return vfoo(As...); };
-
-auto GL4 = [](int i, char c, auto* ... As) -> int { return vfoo(As...); };
-
-
-void foo() {
-  auto GL1 = [](auto a, int i) -> int { return id(a); };
-
-  auto GL2 = [](auto ... As) -> int { return vfoo(As...); };
-}
-
-int main()
-{
-  auto l1 = [](auto a) -> int { return a + 5; };
-  auto l2 = [](auto *p) -> int { return p + 5; };
-  struct A { int i; char f(int) { return 'c'; } };
-  auto l3 = [](auto &&ur, 
-                auto &lr, 
-                auto v, 
-                int i, 
-                auto* p,
-                auto A::*memvar,
-                auto (A::*memfun)(int),
-                char c,
-                decltype (v)* pv
-                , auto (&array)[5] 
-              ) -> int { return v + i + c
-                          + array[0]; 
-                       };
-  int arr[5] = {0, 1, 2, 3, 4 };
-  int lval = 0;
-  double d = 3.14;
-  l3(3, lval, d, lval, &lval, &A::i, &A::f, 'c', &d, arr);
-  auto l4 = [](decltype(auto) a) -> int { return 0; }; //expected-error{{decltype(auto)}}
-  {
-    struct Local {
-      static int ifi(int i) { return i; }
-      static char cfi(int) { return 'a'; }
-      static double dfi(int i) { return i + 3.14; }
-      static Local localfi(int) { return Local{}; }
-    };
-    auto l4 = [](auto (*fp)(int)) -> int { return fp(3); }; //expected-error{{no viable conversion from 'Local' to 'int'}} 
-    l4(&Local::ifi);
-    l4(&Local::cfi);
-    l4(&Local::dfi);
-    l4(&Local::localfi); //expected-note{{in instantiation of function template specialization}}  
-  }
-  {
-    auto unnamed_parameter = [](auto, auto) -> void { };
-    unnamed_parameter(3, '4');
-  }
-  {
-    auto l = [](auto 
-                      (*)(auto)) { }; //expected-error{{'auto' not allowed}}
-    //FIXME: These diagnostics might need some work.
-    auto l2 = [](char auto::*pm) { };  //expected-error{{cannot combine with previous}}\
-                                         expected-error{{'pm' does not point into a class}}
-    auto l3 = [](char (auto::*pmf)()) { };  //expected-error{{'auto' not allowed}}\
-                                              expected-error{{'pmf' does not point into a class}}\
-                                              expected-error{{function cannot return function type 'char ()'}}
-  }
-}
-
-
diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/generic-lambda-unimplemented-1y.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/generic-lambda-unimplemented-1y.cpp
deleted file mode 100644 (file)
index fcfd9bc..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-// RUN: %clang_cc1 -fsyntax-only -std=c++1y %s -verify -emit-llvm
-namespace return_type_deduction_ok {
-// FIXME: Once return type deduction is implemented for generic lambdas
-// this will need to be updated.
- auto l = [](auto a) ->auto { return a; }(2); 
- auto l2 = [](auto a) ->decltype(auto) { return a; }(2);  
- auto l3 = [](auto a) { return a; }(2); 
-
-
-}
-
-namespace lambda_capturing {
-// FIXME: Once return type deduction is implemented for generic lambdas
-// this will need to be updated.
-void test() {
-  int i = 10;
-  auto L = [=](auto a) -> int { //expected-error{{unimplemented}}
-    return i + a;
-  };
-  L(3); 
-}
-
-}
-
-namespace nested_generic_lambdas {
-void test() {
-  auto L = [](auto a) -> int {
-    auto M = [](auto b, decltype(a) b2) -> int { //expected-error{{unimplemented}}
-      return 1;
-    };
-    M(a, a);
-  };
-  L(3); //expected-note{{in instantiation of}}
-}
-}
-
-namespace conversion_operator {
-void test() {
-    auto L = [](auto a) -> int { return a; };
-    int (*fp)(int) = L;  //expected-error{{no viable conversion}}
-  }
-}
-
-namespace generic_lambda_as_default_argument_ok {
-  void test(int i = [](auto a)->int { return a; }(3)) {
-  
-  }
-  
-}
-
diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p2-generic-lambda-1y.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p2-generic-lambda-1y.cpp
deleted file mode 100644 (file)
index 44656a3..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++1y -DCXX1Y\r
-\r
-// prvalue\r
-void prvalue() {\r
-  auto&& x = [](auto a)->void { };\r
-  auto& y = [](auto *a)->void { }; // expected-error{{cannot bind to a temporary of type}}\r
-}\r
-\r
-namespace std {\r
-  class type_info;\r
-}\r
-\r
-struct P {\r
-  virtual ~P();\r
-};\r
-\r
-void unevaluated_operand(P &p, int i) {\r
-  // FIXME: this should only emit one error.\r
-  int i2 = sizeof([](auto a, auto b)->void{}(3, '4')); // expected-error{{lambda expression in an unevaluated operand}} \\r
-                                                       // expected-error{{invalid application of 'sizeof'}}\r
-  const std::type_info &ti1 = typeid([](auto &a) -> P& { static P p; return p; }(i));\r
-  const std::type_info &ti2 = typeid([](auto) -> int { return i; }(i));  // expected-error{{lambda expression in an unevaluated operand}}\r
-}\r
index f846133..79ee76f 100644 (file)
@@ -7,60 +7,3 @@ int &d = [] (int &r) -> auto & { return r; } (a);
 int &e = [] (int &r) -> auto { return r; } (a); // expected-error {{cannot bind to a temporary}}
 int &f = [] (int r) -> decltype(auto) { return r; } (a); // expected-error {{cannot bind to a temporary}}
 int &g = [] (int r) -> decltype(auto) { return (r); } (a); // expected-warning {{reference to stack}}
-
-
-int test_explicit_auto_return() 
-{
-    struct X {};
-    auto L = [](auto F, auto a) { return F(a); };
-    auto M = [](auto a) -> auto { return a; }; // OK
-    auto MRef = [](auto b) -> auto& { return b; }; //expected-warning{{reference to stack}}
-    auto MPtr = [](auto c) -> auto* { return &c; }; //expected-warning{{address of stack}}
-    auto MDeclType = [](auto&& d) -> decltype(auto) { return static_cast<decltype(d)>(d); }; //OK
-    M(3);
-    
-    auto &&x = MDeclType(X{});
-    auto &&x1 = M(X{});
-    auto &&x2 = MRef(X{});//expected-note{{in instantiation of}}
-    auto &&x3 = MPtr(X{}); //expected-note{{in instantiation of}}
-    return 0;    
-}
-
-int test_implicit_auto_return() 
-{  
-  {
-    auto M = [](auto a) { return a; };
-    struct X {};
-    X x = M(X{});
-    
-  }
-}
-int test_multiple_returns()  {
-    auto M = [](auto a) { 
-      bool k;
-      if (k)
-        return a;
-      else
-        return 5; //expected-error{{deduced as 'int' here}}
-    }; 
-    M(3); // OK
-    M('a'); //expected-note{{in instantiation of}}
-  return 0;
-}
-int test_no_parameter_list()
-{
-  static int si = 0;
-    auto M = [] { return 5; }; // OK
-    auto M2 = [] -> auto&& { return si; }; // expected-error{{lambda requires '()'}}
-    M();
-}
-
-int test_conditional_in_return() {
-  auto Fac = [](auto f, auto n) { 
-    return n <= 0 ? n : f(f, n - 1) * n;
-  };
-  // FIXME: this test causes a recursive limit - need to error more gracefully.
-  //Fac(Fac, 3);
-
-}
\ No newline at end of file
index 1016cb1..c69aa11 100644 (file)
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify
-// RUN: %clang_cc1 -fsyntax-only -std=c++1y %s -verify -DCPP1Y
+// RUN: %clang_cc1 -fsyntax-only -std=c++1y %s -verify
 
 void missing_lambda_declarator() {
   [](){}();
@@ -18,7 +18,7 @@ void infer_void_return_type(int i) {
     switch (x) {
     case 0: return get<void>();
     case 1: return;
-    case 2: return { 1, 2.0 }; //expected-error{{cannot deduce}}
+    case 2: return { 1, 2.0 }; // expected-error{{cannot deduce lambda return type from initializer list}}
     }
   }(7);
 }
diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p5-generic-lambda-1y.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p5-generic-lambda-1y.cpp
deleted file mode 100644 (file)
index c131161..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++1y -DCXX1Y -emit-llvm\r
-\r
-namespace test_factorial {\r
-\r
-auto Fact = [](auto Self, unsigned n) -> unsigned {\r
-    return !n ? 1 : Self(Self, n - 1) * n;\r
-};\r
-\r
-auto six = Fact(Fact, 3);\r
-\r
-}\r
-\r
-namespace overload_generic_lambda {\r
-  template <class F1, class F2> struct overload : F1, F2 {\r
-    using F1::operator();\r
-    using F2::operator();\r
-    overload(F1 f1, F2 f2) : F1(f1), F2(f2) { }\r
-  };\r
-\r
-  auto NumParams = [](auto Self, auto h, auto ... rest) -> unsigned {\r
-    return 1 + Self(Self, rest...);\r
-  };\r
-  auto Base = [](auto Self, auto h) -> unsigned {\r
-      return 1;\r
-  };\r
-  overload<decltype(Base), decltype(NumParams)> O(Base, NumParams);\r
-  int num_params =  O(O, 5, 3, "abc", 3.14, 'a');\r
-}\r
-\r
-\r
-namespace overload_generic_lambda_return_type_deduction {\r
-  template <class F1, class F2> struct overload : F1, F2 {\r
-    using F1::operator();\r
-    using F2::operator();\r
-    overload(F1 f1, F2 f2) : F1(f1), F2(f2) { }\r
-  };\r
-\r
-  auto NumParams = [](auto Self, auto h, auto ... rest) {\r
-    return 1 + Self(Self, rest...);\r
-  };\r
-  auto Base = [](auto Self, auto h) {\r
-      return 1;\r
-  };\r
-  overload<decltype(Base), decltype(NumParams)> O(Base, NumParams);\r
-  int num_params =  O(O, 5, 3, "abc", 3.14, 'a');\r
-}\r
-\r
-namespace test_standard_p5 {\r
-// FIXME: This test should eventually compile without an explicit trailing return type\r
-auto glambda = [](auto a, auto&& b) ->bool { return a < b; };\r
-bool b = glambda(3, 3.14); // OK\r
-\r
-}\r
-namespace test_deduction_failure {\r
- int test() {\r
-   auto g = [](auto *a) { //expected-note{{candidate template ignored}}\r
-    return a;\r
-   };\r
-   struct X { };\r
-   X *x;\r
-   g(x);\r
-   g(3); //expected-error{{no matching function}}\r
-   return 0;\r
- }\r
-\r
-}\r
-  \r
-namespace test_instantiation_or_sfinae_failure {\r
-int test2() {\r
-  {\r
-    auto L = [](auto *a) { \r
-                return (*a)(a); }; //expected-error{{called object type 'double' is not a function}}\r
-    //l(&l);\r
-    double d;\r
-    L(&d); //expected-note{{in instantiation of}}\r
-    auto M = [](auto b) { return b; };\r
-    L(&M); // ok\r
-  }\r
-  {\r
-    auto L = [](auto *a) ->decltype (a->foo()) { //expected-note2{{candidate template ignored:}}\r
-                return (*a)(a); }; \r
-    //l(&l);\r
-    double d;\r
-    L(&d); //expected-error{{no matching function for call}} \r
-    auto M = [](auto b) { return b; };\r
-    L(&M); //expected-error{{no matching function for call}} \r
\r
-  }\r
-  return 0;\r
-}\r
-\r
-\r
-}\r
-  \r
-namespace test_misc {\r
-auto GL = [](auto a, decltype(a) b) //expected-note{{candidate function}} \r
-                -> int { return a + b; };\r
-\r
-void test() {\r
-   struct X { };\r
-   GL(3, X{}); //expected-error{{no matching function}}\r
-}\r
-\r
-void test2() {\r
-  auto l = [](auto *a) -> int { \r
-              (*a)(a); return 0; }; //expected-error{{called object type 'double' is not a function}}\r
-  l(&l);\r
-  double d;\r
-  l(&d); //expected-note{{in instantiation of}}\r
-}\r
-\r
-}\r
-\r
-namespace nested_lambdas {\r
-  int test() {\r
-    auto L = [](auto a) {\r
-                 return [=](auto b) {  //expected-error{{unimplemented}}\r
-                           return a + b;\r
-                        };\r
-              };\r
-   // auto M = L(3.14);\r
-   // return M('4');    \r
-  }\r
-  auto get_lambda() {\r
-    return [](auto a) {\r
-      return a; \r
-    };\r
-  };\r
-  \r
-  int test2() {\r
-    auto L = get_lambda();\r
-    L(3);\r
-  }\r
-}\r
-\r