]> granicus.if.org Git - clang/commitdiff
Revert r193223 and r193216.
authorRafael Espindola <rafael.espindola@gmail.com>
Wed, 23 Oct 2013 04:12:23 +0000 (04:12 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Wed, 23 Oct 2013 04:12:23 +0000 (04:12 +0000)
They were causing CodeGenCXX/mangle-exprs.cpp to fail.

Revert "Remove the circular reference to LambdaExpr in CXXRecordDecl."

Revert "Again: Teach TreeTransform and family how to transform generic lambdas nested within templates and themselves."

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@193226 91177308-0d34-0410-b5e6-96231b3b80d8

13 files changed:
include/clang/AST/DeclCXX.h
include/clang/Sema/Sema.h
lib/AST/DeclCXX.cpp
lib/Sema/SemaDecl.cpp
lib/Sema/SemaLambda.cpp
lib/Sema/SemaTemplateInstantiate.cpp
lib/Sema/SemaTemplateInstantiateDecl.cpp
lib/Sema/TreeTransform.h
lib/Serialization/ASTReaderDecl.cpp
lib/Serialization/ASTWriter.cpp
test/CXX/expr/expr.prim/expr.prim.lambda/generic-lambda-unimplemented-1y.cpp
test/PCH/cxx1y-lambdas.mm [deleted file]
test/SemaCXX/cxx1y-generic-lambdas.cpp

index 9a53b9e9fc2fddb8e91f951aa73362a154ea33f7..bb97b55f123c7ed4732a2fc11817ccc0a6cedb56 100644 (file)
@@ -514,12 +514,10 @@ class CXXRecordDecl : public RecordDecl {
   struct LambdaDefinitionData : public DefinitionData {
     typedef LambdaExpr::Capture Capture;
     
-       LambdaDefinitionData(CXXRecordDecl *D, TypeSourceInfo *Info, 
-                         bool Dependent, bool IsGeneric, 
-                         LambdaCaptureDefault CaptureDefault) 
-      : DefinitionData(D), Dependent(Dependent), IsGenericLambda(IsGeneric), 
-        CaptureDefault(CaptureDefault), NumCaptures(0), NumExplicitCaptures(0), 
-        ManglingNumber(0), ContextDecl(0), Captures(0), MethodTyInfo(Info)
+    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) 
     {
       IsLambda = true;
     }
@@ -534,17 +532,11 @@ class CXXRecordDecl : public RecordDecl {
     /// artifact of having to parse the default arguments before. 
     unsigned Dependent : 1;
     
-    /// \brief Whether this lambda is a generic lambda.
-    unsigned IsGenericLambda : 1;
-
-    /// \brief The Default Capture.
-    unsigned CaptureDefault : 2;
-
-    /// \brief The number of captures in this lambda is limited 2^NumCaptures.
-    unsigned NumCaptures : 15;
+    /// \brief The number of captures in this lambda.
+    unsigned NumCaptures : 16;
 
     /// \brief The number of explicit captures in this lambda.
-    unsigned NumExplicitCaptures : 13;
+    unsigned NumExplicitCaptures : 15;
 
     /// \brief The number used to indicate this lambda expression for name 
     /// mangling in the Itanium C++ ABI.
@@ -562,6 +554,9 @@ class CXXRecordDecl : public RecordDecl {
 
     /// \brief The type of the call method.
     TypeSourceInfo *MethodTyInfo;
+
+    /// \brief The AST node of the lambda expression.
+    LambdaExpr *TheLambdaExpr;
        
   };
 
@@ -674,8 +669,7 @@ public:
                                bool DelayTypeCreation = false);
   static CXXRecordDecl *CreateLambda(const ASTContext &C, DeclContext *DC,
                                      TypeSourceInfo *Info, SourceLocation Loc,
-                                     bool DependentLambda, bool IsGeneric, 
-                                     LambdaCaptureDefault CaptureDefault);
+                                     bool DependentLambda);
   static CXXRecordDecl *CreateDeserialized(const ASTContext &C, unsigned ID);
 
   bool isDynamicClass() const {
@@ -1019,11 +1013,17 @@ public:
   /// lambda.
   TemplateParameterList *getGenericLambdaTemplateParameterList() const;
 
-  LambdaCaptureDefault getLambdaCaptureDefault() const {
-    assert(isLambda());
-    return static_cast<LambdaCaptureDefault>(getLambdaData().CaptureDefault);
+  /// \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 00e74a812f58444e36622ecc22d5973c74c79fe3..abbf512f3c15f0c6d6bbd791d6cee6bd9999d743 100644 (file)
@@ -4453,8 +4453,7 @@ public:
   /// \brief Create a new lambda closure type.
   CXXRecordDecl *createLambdaClosureType(SourceRange IntroducerRange,
                                          TypeSourceInfo *Info,
-                                         bool KnownDependent, 
-                                         LambdaCaptureDefault CaptureDefault);
+                                         bool KnownDependent);
 
   /// \brief Start the definition of a lambda expression.
   CXXMethodDecl *startLambdaDefinition(CXXRecordDecl *Class,
index ee25f65d49da1a7e14e60be3ac1d950e52335577..cdf5e9f1f5c0cffef561a430eb2af4a06d01fcce 100644 (file)
@@ -108,15 +108,11 @@ CXXRecordDecl *CXXRecordDecl::Create(const ASTContext &C, TagKind TK,
 
 CXXRecordDecl *CXXRecordDecl::CreateLambda(const ASTContext &C, DeclContext *DC,
                                            TypeSourceInfo *Info, SourceLocation Loc,
-                                           bool Dependent, bool IsGeneric, 
-                                           LambdaCaptureDefault CaptureDefault) {
+                                           bool Dependent) {
   CXXRecordDecl* R = new (C) CXXRecordDecl(CXXRecord, TTK_Class, DC, Loc, Loc,
                                            0, 0);
   R->IsBeingDefined = true;
-  R->DefinitionData = new (C) struct LambdaDefinitionData(R, Info, 
-                                                          Dependent, 
-                                                          IsGeneric, 
-                                                          CaptureDefault);
+  R->DefinitionData = new (C) struct LambdaDefinitionData(R, Info, Dependent);
   R->MayHaveOutOfDateDef = false;
   R->setImplicit(true);
   C.getTypeDeclType(R, /*PrevDecl=*/0);
@@ -946,10 +942,10 @@ bool CXXRecordDecl::isCLike() const {
 
   return isPOD() && data().HasOnlyCMembers;
 }
+
 bool CXXRecordDecl::isGenericLambda() const { 
-  if (!isLambda()) return false;
-  return getLambdaData().IsGenericLambda;
+  return isLambda() && 
+      getLambdaCallOperator()->getDescribedFunctionTemplate(); 
 }
 
 CXXMethodDecl* CXXRecordDecl::getLambdaCallOperator() const {
index bc7be6d4593ea4bfb253891a3e628d39e26642cb..80f95e68690098b8d693d7e2fa89c0d0e1b4f10e 100644 (file)
@@ -9401,29 +9401,6 @@ Sema::CheckForFunctionRedefinition(FunctionDecl *FD,
   Diag(Definition->getLocation(), diag::note_previous_definition);
   FD->setInvalidDecl();
 }
-static void RebuildLambdaScopeInfo(CXXMethodDecl *CallOperator, 
-                                   Sema &S) {
-  CXXRecordDecl *const LambdaClass = CallOperator->getParent();
-  S.PushLambdaScope();
-  LambdaScopeInfo *LSI = S.getCurLambda();
-  LSI->CallOperator = CallOperator;
-  LSI->Lambda = LambdaClass;
-  LSI->ReturnType = CallOperator->getResultType();
-  const LambdaCaptureDefault LCD = LambdaClass->getLambdaCaptureDefault();
-
-  if (LCD == LCD_None)
-    LSI->ImpCaptureStyle = CapturingScopeInfo::ImpCap_None;
-  else if (LCD == LCD_ByCopy)
-    LSI->ImpCaptureStyle = CapturingScopeInfo::ImpCap_LambdaByval;
-  else if (LCD == LCD_ByRef)
-    LSI->ImpCaptureStyle = CapturingScopeInfo::ImpCap_LambdaByref;
-  DeclarationNameInfo DNI = CallOperator->getNameInfo();
-    
-  LSI->IntroducerRange = DNI.getCXXOperatorNameRange(); 
-  LSI->Mutable = !CallOperator->isConst();
-
-  // FIXME: Add the captures to the LSI.
-}
 
 Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D) {
   // Clear the last template instantiation error context.
@@ -9439,18 +9416,31 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D) {
     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) to prime the current 
-  // LambdaScopeInfo.  
-  // When the template operator is being specialized, the LambdaScopeInfo,
-  // has to be properly restored so that tryCaptureVariable doesn't try
-  // and capture any new variables. In addition when calculating potential
-  // captures during transformation of nested lambdas, it is necessary to 
-  // have the LSI properly restored. 
+  // that's already been calculated (ActOnLambdaExpr) when analyzing the
+  // template version, to prime the current LambdaScopeInfo. 
   if (isGenericLambdaCallOperatorSpecialization(FD)) {
+    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!");
-    RebuildLambdaScopeInfo(cast<CXXMethodDecl>(D), *this);
+    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
@@ -9814,6 +9804,7 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
     PopDeclContext();
 
   PopFunctionScopeInfo(ActivePolicy, dcl);
+  
   // If any errors have occurred, clear out any temporaries that may have
   // been leftover. This ensures that these temporaries won't be picked up for
   // deletion in some later function.
index 9b3afc999020004b5f2d30b0c782c0fbb582a65a..32a385caaa559fe349bd376464e371a55758d112 100644 (file)
 using namespace clang;
 using namespace sema;
 
-
-static inline TemplateParameterList *
-getGenericLambdaTemplateParameterList(LambdaScopeInfo *LSI, Sema &SemaRef) {
-  if (LSI->GLTemplateParameterList)
-    return LSI->GLTemplateParameterList;
-
-  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;
-}
-
-
-
 CXXRecordDecl *Sema::createLambdaClosureType(SourceRange IntroducerRange,
                                              TypeSourceInfo *Info,
-                                             bool KnownDependent, 
-                                             LambdaCaptureDefault CaptureDefault) {
+                                             bool KnownDependent) {
   DeclContext *DC = CurContext;
   while (!(DC->isFunctionOrMethod() || DC->isRecord() || DC->isFileContext()))
     DC = DC->getParent();
-  bool IsGenericLambda = getGenericLambdaTemplateParameterList(getCurLambda(),
-                                                               *this);  
+  
   // Start constructing the lambda class.
   CXXRecordDecl *Class = CXXRecordDecl::CreateLambda(Context, DC, Info,
                                                      IntroducerRange.getBegin(),
-                                                     KnownDependent, 
-                                                     IsGenericLambda, 
-                                                     CaptureDefault);
+                                                     KnownDependent);
   DC->addDecl(Class);
   
   return Class;
@@ -157,6 +131,25 @@ Sema::ExpressionEvaluationContextRecord::getMangleNumberingContext(
   return *MangleNumbering;
 }
 
+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 *MethodTypeInfo,
@@ -250,8 +243,7 @@ void Sema::buildLambdaScope(LambdaScopeInfo *LSI,
                                         bool ExplicitResultType,
                                         bool Mutable) {
   LSI->CallOperator = CallOperator;
-  CXXRecordDecl *LambdaClass = CallOperator->getParent();
-  LSI->Lambda = LambdaClass;
+  LSI->Lambda = CallOperator->getParent();
   if (CaptureDefault == LCD_ByCopy)
     LSI->ImpCaptureStyle = LambdaScopeInfo::ImpCap_LambdaByval;
   else if (CaptureDefault == LCD_ByRef)
@@ -636,7 +628,7 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
   }
 
   CXXRecordDecl *Class = createLambdaClosureType(Intro.Range, MethodTyInfo,
-                                                 KnownDependent, Intro.Default);
+                                                 KnownDependent);
 
   CXXMethodDecl *Method = startLambdaDefinition(Class, Intro.Range,
                                                 MethodTyInfo, EndLoc, Params);
@@ -1163,6 +1155,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).
index 3c621dafab9dc33e02337e8dab5356fe25827c5f..f13b14bd0f1bcf654c87552f4899c5271b3d39bb 100644 (file)
@@ -14,7 +14,6 @@
 #include "TreeTransform.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
-#include "clang/AST/ASTLambda.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/Expr.h"
 #include "clang/Basic/LangOptions.h"
@@ -131,11 +130,6 @@ Sema::getTemplateInstantiationArgs(NamedDecl *D,
         assert(Function->getPrimaryTemplate() && "No function template?");
         if (Function->getPrimaryTemplate()->isMemberSpecialization())
           break;
-
-        // If this function is a generic lambda specialization, we are done.
-        if (isGenericLambdaCallOperatorSpecialization(Function))
-          break;
-
       } else if (FunctionTemplateDecl *FunTmpl
                                    = Function->getDescribedFunctionTemplate()) {
         // Add the "injected" template arguments.
@@ -917,36 +911,13 @@ namespace {
     }
 
     ExprResult TransformLambdaScope(LambdaExpr *E,
-                                    CXXMethodDecl *NewCallOperator) {
-      CXXMethodDecl *const OldCallOperator = E->getCallOperator();   
-      // In the generic lambda case, we set the NewTemplate to be considered
-      // an "instantiation" of the OldTemplate.
-      if (FunctionTemplateDecl *const NewCallOperatorTemplate = 
-            NewCallOperator->getDescribedFunctionTemplate()) {
-        
-        FunctionTemplateDecl *const OldCallOperatorTemplate = 
-                              OldCallOperator->getDescribedFunctionTemplate();
-        NewCallOperatorTemplate->setInstantiatedFromMemberTemplate(
-                                                     OldCallOperatorTemplate);
-        // Mark the NewCallOperatorTemplate a specialization.  
-        NewCallOperatorTemplate->setMemberSpecialization();
-      } else 
-        // For a non-generic lambda we set the NewCallOperator to 
-        // be an instantiation of the OldCallOperator.
-        NewCallOperator->setInstantiationOfMemberFunction(OldCallOperator,
-                                                    TSK_ImplicitInstantiation);
-      
-      return inherited::TransformLambdaScope(E, NewCallOperator);
-    }
-    TemplateParameterList *TransformTemplateParameterList(\r
-                              TemplateParameterList *OrigTPL)  {
-      if (!OrigTPL || !OrigTPL->size()) return OrigTPL;
-         
-      DeclContext *Owner = OrigTPL->getParam(0)->getDeclContext();
-      TemplateDeclInstantiator  DeclInstantiator(getSema(), 
-                        /* DeclContext *Owner */ Owner, TemplateArgs);
-      return DeclInstantiator.SubstTemplateParams(OrigTPL); 
+                                    CXXMethodDecl *CallOperator) {
+      CallOperator->setInstantiationOfMemberFunction(E->getCallOperator(),
+                                                     TSK_ImplicitInstantiation);
+      return TreeTransform<TemplateInstantiator>::
+         TransformLambdaScope(E, CallOperator);
     }
+
   private:
     ExprResult transformNonTypeTemplateParmRef(NonTypeTemplateParmDecl *parm,
                                                SourceLocation loc,
index d0c3ac69144e79178f3f7b915c9ba807a96b0e0e..d1512c271c0166773ebcf1fba5230205f12d2ba9 100644 (file)
@@ -4174,8 +4174,7 @@ DeclContext *Sema::FindInstantiatedContext(SourceLocation Loc, DeclContext* DC,
 NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,
                           const MultiLevelTemplateArgumentList &TemplateArgs) {
   DeclContext *ParentDC = D->getDeclContext();
-
-  if (isa<NonTypeTemplateParmDecl>(D) ||
+  if (isa<ParmVarDecl>(D) || isa<NonTypeTemplateParmDecl>(D) ||
       isa<TemplateTypeParmDecl>(D) || isa<TemplateTemplateParmDecl>(D) ||
       (ParentDC->isFunctionOrMethod() && ParentDC->isDependentContext()) ||
       (isa<CXXRecordDecl>(D) && cast<CXXRecordDecl>(D)->isLambda())) {
index 2d22e4ca6473a808f444e64372d81dda4aa9a85c..97e12d77a194258b6a84a996df755e5a7a6ffddf 100644 (file)
@@ -593,11 +593,6 @@ public:
   /// \brief Transform the captures and body of a lambda expression.
   ExprResult TransformLambdaScope(LambdaExpr *E, CXXMethodDecl *CallOperator);
 
-  TemplateParameterList *TransformTemplateParameterList(
-        TemplateParameterList *TPL) {
-    return TPL;
-  }
-
   ExprResult TransformAddressOfOperand(Expr *E);
   ExprResult TransformDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E,
                                                 bool IsAddressOfOperand);
@@ -8272,102 +8267,48 @@ template<typename Derived>
 ExprResult
 TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
  
-  getSema().PushLambdaScope();
-  LambdaScopeInfo *LSI = getSema().getCurLambda();
-  // Transform the template parameters, and add them to the current
-  // instantiation scope. The null case is handled correctly.
-  LSI->GLTemplateParameterList = getDerived().TransformTemplateParameterList(
-      E->getTemplateParameterList());
-
-  // Check to see if the TypeSourceInfo of the call operator needs to
-  // be transformed, and if so do the transformation in the 
-  // CurrentInstantiationScope.
-
-  TypeSourceInfo *OldCallOpTSI = E->getCallOperator()->getTypeSourceInfo();
-  FunctionProtoTypeLoc OldCallOpFPTL = 
-      OldCallOpTSI->getTypeLoc().getAs<FunctionProtoTypeLoc>();
-  TypeSourceInfo *NewCallOpTSI = 0;
-  
-  const bool CallOpWasAlreadyTransformed = 
-      getDerived().AlreadyTransformed(OldCallOpTSI->getType()); 
-  
-  // Use the Old Call Operator's TypeSourceInfo if it is already transformed.
-  if (CallOpWasAlreadyTransformed)  
-    NewCallOpTSI = OldCallOpTSI;  
-  else {
-    // Transform the TypeSourceInfo of the Original Lambda's Call Operator.
-    // The transformation MUST be done in the CurrentInstantiationScope since
-    // it introduces a mapping of the original to the newly created 
-    // transformed parameters.
-
-    TypeLocBuilder NewCallOpTLBuilder;
-    QualType NewCallOpType = TransformFunctionProtoType(NewCallOpTLBuilder, 
-                                                        OldCallOpFPTL, 
-                                                        0, 0);
-    NewCallOpTSI = NewCallOpTLBuilder.getTypeSourceInfo(getSema().Context,
-                                                        NewCallOpType);
-  }
-  // Extract the ParmVarDecls from the NewCallOpTSI and add them to
-  // the vector below - this will be used to synthesize the 
-  // NewCallOperator.  Additionally, add the parameters of the untransformed 
-  // lambda call operator to the CurrentInstantiationScope.
-  SmallVector<ParmVarDecl *, 4> Params;  
-  {
-    FunctionProtoTypeLoc NewCallOpFPTL = 
-        NewCallOpTSI->getTypeLoc().castAs<FunctionProtoTypeLoc>();
-    ParmVarDecl **NewParamDeclArray = NewCallOpFPTL.getParmArray();
-    const unsigned NewNumArgs = NewCallOpFPTL.getNumArgs();
-
-    for (unsigned I = 0; I < NewNumArgs; ++I) {
-      // If this call operator's type does not require transformation, 
-      // the parameters do not get added to the current instantiation scope, 
-      // - so ADD them! This allows the following to compile when the enclosing
-      // template is specialized and the entire lambda expression has to be
-      // transformed. 
-      // template<class T> void foo(T t) {
-      //   auto L = [](auto a) {
-      //       auto M = [](char b) { <-- note: non-generic lambda
-      //         auto N = [](auto c) {
-      //            int x = sizeof(a);
-      //            x = sizeof(b); <-- specifically this line
-      //            x = sizeof(c);
-      //          };
-      //        };
-      //      };
-      //    }
-      // foo('a')
-      if (CallOpWasAlreadyTransformed)
-        getDerived().transformedLocalDecl(NewParamDeclArray[I],
-                                          NewParamDeclArray[I]);
-      // Add to Params array, so these parameters can be used to create
-      // the newly transformed call operator.
-      Params.push_back(NewParamDeclArray[I]);
-    }
+  // FIXME: Implement nested generic lambda transformations.
+  if (E->isGenericLambda()) {
+    getSema().Diag(E->getIntroducerRange().getBegin(), 
+      diag::err_glambda_not_fully_implemented) 
+      << " template transformation of generic lambdas not implemented yet";
+    return ExprError();
   }
-
-  if (!NewCallOpTSI)
+  // Transform the type of the lambda parameters and start the definition of
+  // the lambda itself.
+  TypeSourceInfo *MethodTy
+    = TransformType(E->getCallOperator()->getTypeSourceInfo());
+  if (!MethodTy)
     return ExprError();
 
   // Create the local class that will describe the lambda.
   CXXRecordDecl *Class
     = getSema().createLambdaClosureType(E->getIntroducerRange(),
-                                        NewCallOpTSI,
-                                        /*KnownDependent=*/false,
-                                        E->getCaptureDefault());
-
+                                        MethodTy,
+                                        /*KnownDependent=*/false);
   getDerived().transformedLocalDecl(E->getLambdaClass(), Class);
 
+  // Transform lambda parameters.
+  SmallVector<QualType, 4> ParamTypes;
+  SmallVector<ParmVarDecl *, 4> Params;
+  if (getDerived().TransformFunctionTypeParams(E->getLocStart(),
+        E->getCallOperator()->param_begin(),
+        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 *NewCallOperator
+  CXXMethodDecl *CallOperator
     = getSema().startLambdaDefinition(Class, E->getIntroducerRange(),
-                                      NewCallOpTSI,
+                                      MethodTy,
                                       E->getCallOperator()->getLocEnd(),
                                       Params);
-  LSI->CallOperator = NewCallOperator;
-
-  getDerived().transformAttrs(E->getCallOperator(), NewCallOperator);
+  getDerived().transformAttrs(E->getCallOperator(), CallOperator);
 
-  return getDerived().TransformLambdaScope(E, NewCallOperator);
+  return getDerived().TransformLambdaScope(E, CallOperator);
 }
 
 template<typename Derived>
index 0c885bc5792146a7a0b8752c5e1034b9bed5f67c..463af777986f9cb212f9b8f4a0913dd3dc13378f 100644 (file)
@@ -1226,8 +1226,6 @@ void ASTDeclReader::ReadCXXDefinitionData(
     CXXRecordDecl::LambdaDefinitionData &Lambda
       = static_cast<CXXRecordDecl::LambdaDefinitionData &>(Data);
     Lambda.Dependent = Record[Idx++];
-    Lambda.IsGenericLambda = Record[Idx++];
-    Lambda.CaptureDefault = Record[Idx++];
     Lambda.NumCaptures = Record[Idx++];
     Lambda.NumExplicitCaptures = Record[Idx++];
     Lambda.ManglingNumber = Record[Idx++];
@@ -1236,6 +1234,7 @@ 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++];
@@ -1267,8 +1266,7 @@ ASTDeclReader::VisitCXXRecordDeclImpl(CXXRecordDecl *D) {
     bool IsLambda = Record[Idx++];
     if (IsLambda)
       D->DefinitionData = new (C) CXXRecordDecl::LambdaDefinitionData(D, 0,
-                                                                      false,
-                                                                      false, LCD_None);
+                                                                      false);
     else
       D->DefinitionData = new (C) struct CXXRecordDecl::DefinitionData(D);
 
index 3d14512540fa79ff6df19078184c4be755ba8662..3ee9830e7cb036356bcd20b9ecd3244502db907d 100644 (file)
@@ -5129,13 +5129,12 @@ void ASTWriter::AddCXXDefinitionData(const CXXRecordDecl *D, RecordDataImpl &Rec
   if (Data.IsLambda) {
     CXXRecordDecl::LambdaDefinitionData &Lambda = D->getLambdaData();
     Record.push_back(Lambda.Dependent);
-    Record.push_back(Lambda.IsGenericLambda);
-    Record.push_back(Lambda.CaptureDefault);
     Record.push_back(Lambda.NumCaptures);
     Record.push_back(Lambda.NumExplicitCaptures);
     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);
index 92dd7ad1876c54aeaf50314782899dc8571fd5f2..a43a98bb18f859a939a46d630561c6d238e9e9bc 100644 (file)
@@ -29,3 +29,20 @@ void test() {
 
 }
 
+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}}
+}
+template<class T> void foo(T) {
+ auto L = [](auto a) { return a; }; //expected-error{{unimplemented}}
+}
+template void foo(int); //expected-note{{in instantiation of}}
+}
+
+
diff --git a/test/PCH/cxx1y-lambdas.mm b/test/PCH/cxx1y-lambdas.mm
deleted file mode 100644 (file)
index ee4a2ba..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-// RUN: %clang_cc1 -pedantic-errors -fblocks -std=c++1y -emit-pch %s -o %t-cxx1y\r
-// RUN: %clang_cc1 -ast-print -pedantic-errors -fblocks -std=c++1y -include-pch %t-cxx1y  %s | FileCheck -check-prefix=CHECK-PRINT %s\r
-\r
-#ifndef HEADER_INCLUDED\r
-\r
-#define HEADER_INCLUDED\r
-template<typename T>\r
-T add_slowly(const T& x, const T &y) {\r
-  return [](auto z, int y = 0) { return z + y; }(5);\r
-};\r
-\r
-inline int add_int_slowly_twice(int x, int y) {\r
-  int i = add_slowly(x, y);\r
-  auto lambda = [](auto z) { return z + z; };\r
-  return i + lambda(y);\r
-}\r
-\r
-inline int sum_array(int n) {\r
-  auto lambda = [](auto N) -> int {\r
-    int sum = 0;\r
-    int array[5] = { 1, 2, 3, 4, 5};\r
-  \r
-    for (unsigned I = 0; I < N; ++I)\r
-      sum += array[N];\r
-    return sum;\r
-  };\r
-\r
-  return lambda(n);\r
-}\r
-\r
-inline int to_block_pointer(int n) {\r
-  auto lambda = [=](int m) { return n + m; };\r
-  int (^block)(int) = lambda;\r
-  return block(17);\r
-}\r
-\r
-template<typename T>\r
-int init_capture(T t) {\r
-  return [&, x(t)] { return sizeof(x); };\r
-}\r
-\r
-#else\r
-\r
-// CHECK-PRINT: T add_slowly\r
-// CHECK-PRINT: return []\r
-template float add_slowly(const float&, const float&);\r
-\r
-int add(int x, int y) {\r
-  return add_int_slowly_twice(x, y) + sum_array(4) + to_block_pointer(5);\r
-}\r
-\r
-// CHECK-PRINT: inline int add_int_slowly_twice \r
-// CHECK-PRINT: lambda = [] ($auto-0-0 z\r
-\r
-// CHECK-PRINT: init_capture\r
-// CHECK-PRINT: [&, x( t )]\r
-\r
-#endif\r
index 64b9ff14215e2bad5d004786f043045e190001af..b66825a536dc3939b7df65135325df5f42847984 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -emit-llvm -o - %s
+// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks %s
 // DONTRUNYET: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fdelayed-template-parsing %s -DDELAYED_TEMPLATE_PARSING
 // DONTRUNYET: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fms-extensions %s -DMS_EXTENSIONS
 // DONTRUNYET: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fdelayed-template-parsing -fms-extensions %s -DMS_EXTENSIONS -DDELAYED_TEMPLATE_PARSING
@@ -99,8 +99,10 @@ void test() {
                                                   //expected-note{{candidate}}
   }
 }
+
 }
 
+
 namespace return_type_deduction_ok {
  auto l = [](auto a) ->auto { return a; }(2); 
  auto l2 = [](auto a) ->decltype(auto) { return a; }(2);  
@@ -112,516 +114,3 @@ namespace generic_lambda_as_default_argument_ok {
   void test(int i = [](auto a)->int { return a; }(3)) {
   }
 }
-
-namespace nested_non_capturing_lambda_tests {
-template<class ... Ts> void print(Ts ...) { }
-int test() {
-{
-  auto L = [](auto a) {
-    return [](auto b) {
-      return b;
-    };
-  };
-  auto M = L(3);
-  M(4.15);
- }
-{
-  int i = 10; //expected-note{{declared here}}
-  auto L = [](auto a) {
-    return [](auto b) { //expected-note{{begins here}}
-      i = b;  //expected-error{{cannot be implicitly captured}}
-      return b;
-    };
-  };
-  auto M = L(3);
-  M(4.15); //expected-note{{instantiation}}
- }
- {
-  auto L = [](auto a) {
-    print("a = ", a, "\n");
-    return [](auto b) ->decltype(a) {
-      print("b = ", b, "\n");
-      return b;
-    };
-  };
-  auto M = L(3);
-  M(4.15);
- }
-{
-  auto L = [](auto a) ->decltype(a) {
-    print("a = ", a, "\n");
-    return [](auto b) ->decltype(a) { //expected-error{{no viable conversion}}\
-                                      //expected-note{{candidate template ignored}}
-      print("b = ", b, "\n");
-      return b;
-    };
-  };
-  auto M = L(3); //expected-note{{in instantiation of}}
- }
-{
-  auto L = [](auto a) {
-    print("a = ", a, "\n");
-    return [](auto ... b) ->decltype(a) {
-      print("b = ", b ..., "\n");
-      return 4;
-    };
-  };
-  auto M = L(3);
-  M(4.15, 3, "fv");
-}
-
-{
-  auto L = [](auto a) {
-    print("a = ", a, "\n");
-    return [](auto ... b) ->decltype(a) {
-      print("b = ", b ..., "\n");
-      return 4;
-    };
-  };
-  auto M = L(3);
-  int (*fp)(double, int, const char*) = M; 
-  fp(4.15, 3, "fv");
-}
-
-{
-  auto L = [](auto a) {
-    print("a = ", a, "\n");
-    return [](char b) {
-      return [](auto ... c) ->decltype(b) {
-        print("c = ", c ..., "\n");
-        return 42;
-      };
-    };
-  };
-  L(4);
-  auto M = L(3);
-  M('a');
-  auto N = M('x');
-  N("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
-  char (*np)(const char*, int, const char*, double, const char*, int) = N;
-  np("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
-}
-
-
-{
-  auto L = [](auto a) {
-    print("a = ", a, "\n");
-    return [](decltype(a) b) {
-      return [](auto ... c) ->decltype(b) {
-        print("c = ", c ..., "\n");
-        return 42;
-      };
-    };
-  };
-  L('4');
-  auto M = L('3');
-  M('a');
-  auto N = M('x');
-  N("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
-  char (*np)(const char*, int, const char*, double, const char*, int) = N;
-  np("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
-}
-
-
-{
- struct X {
-  static void foo(double d) { } 
-  void test() {
-    auto L = [](auto a) {
-      print("a = ", a, "\n");
-      foo(a);
-      return [](decltype(a) b) {
-        foo(b);
-        foo(sizeof(a) + sizeof(b));
-        return [](auto ... c) ->decltype(b) {
-          print("c = ", c ..., "\n");
-          foo(decltype(b){});
-          foo(sizeof(decltype(a)*) + sizeof(decltype(b)*));
-          return 42;
-        };
-      };
-    };
-    L('4');
-    auto M = L('3');
-    M('a');
-    auto N = M('x');
-    N("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
-    char (*np)(const char*, int, const char*, double, const char*, int) = N;
-    np("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
-  }
-};
-X x;
-x.test();
-}
-// Make sure we can escape the function
-{
- struct X {
-  static void foo(double d) { } 
-  auto test() {
-    auto L = [](auto a) {
-      print("a = ", a, "\n");
-      foo(a);
-      return [](decltype(a) b) {
-        foo(b);
-        foo(sizeof(a) + sizeof(b));
-        return [](auto ... c) ->decltype(b) {
-          print("c = ", c ..., "\n");
-          foo(decltype(b){});
-          foo(sizeof(decltype(a)*) + sizeof(decltype(b)*));
-          return 42;
-        };
-      };
-    };
-    return L;
-  }
-};
-  X x;
-  auto L = x.test();
-  L('4');
-  auto M = L('3');
-  M('a');
-  auto N = M('x');
-  N("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
-  char (*np)(const char*, int, const char*, double, const char*, int) = N;
-  np("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
-}
-
-{
- struct X {
-  static void foo(double d) { } 
-  auto test() {
-    auto L = [](auto a) {
-      print("a = ", a, "\n");
-      foo(a);
-      return [](decltype(a) b) {
-        foo(b);
-        foo(sizeof(a) + sizeof(b));
-        return [](auto ... c) {
-          print("c = ", c ..., "\n");
-          foo(decltype(b){});
-          foo(sizeof(decltype(a)*) + sizeof(decltype(b)*));
-          return [](decltype(c) ... d) ->decltype(a) { //expected-note{{candidate}}
-            print("d = ", d ..., "\n");
-            foo(decltype(b){});
-            foo(sizeof(decltype(a)*) + sizeof(decltype(b)*));
-            return decltype(a){};
-          };
-        };
-      };
-    };
-    return L;
-  }
-};
-  X x;
-  auto L = x.test();
-  L('4');
-  auto M = L('3');
-  M('a');
-  auto N = M('x');
-  auto O = N("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
-  char (*np)(const char*, int, const char*, double, const char*, int) = O;
-  np("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
-  int (*np2)(const char*, int, const char*, double, const char*, int) = O; // expected-error{{no viable conversion}}
-  
-}
-} // end test()
-
-namespace wrapped_within_templates {
-
-namespace explicit_return {
-template<class T> int fooT(T t) {
-  auto L = [](auto a) -> void { 
-    auto M = [](char b) -> void {
-      auto N = [](auto c) -> void {
-        int x = 0;
-        x = sizeof(a);        
-        x = sizeof(b);
-        x = sizeof(c);
-      };  
-      N('a');
-      N(decltype(a){});
-    };    
-  };
-  L(t);
-  L(3.14);
-  return 0;
-}
-
-int run = fooT('a') + fooT(3.14);
-
-} // end explicit_return
-
-namespace implicit_return_deduction {
-template<class T> auto fooT(T t) {
-  auto L = [](auto a)  { 
-    auto M = [](char b)  {
-      auto N = [](auto c)  {
-        int x = 0;
-        x = sizeof(a);        
-        x = sizeof(b);
-        x = sizeof(c);
-      };  
-      N('a');
-      N(decltype(a){});
-    };    
-  };
-  L(t);
-  L(3.14);
-  return 0;
-}
-
-int run = fooT('a') + fooT(3.14);
-
-template<class ... Ts> void print(Ts ... ts) { }
-
-template<class F, class ... Rest> using first = F;
-
-template<class ... Ts> auto fooV(Ts ... ts) {
-  auto L = [](auto ... a) { 
-    auto M = [](decltype(a) ... b) {  
-      auto N = [](auto c) {
-        int x = 0;
-        x = sizeof...(a);        
-        x = sizeof...(b);
-        x = sizeof(c);
-      };  
-      N('a');
-      N(N);
-      N(first<Ts...>{});
-    };
-    M(a...);
-    print("a = ", a..., "\n");    
-  };
-  L(L, ts...);
-  print("ts = ", ts..., "\n");
-  return 0;
-}
-
-int run2 = fooV(3.14, " ", '4', 5) + fooV("BC", 3, 2.77, 'A', float{}, short{}, unsigned{});
-
-} //implicit_return_deduction
-
-
-} //wrapped_within_templates
-
-namespace at_ns_scope {
-  void foo(double d) { }
-  auto test() {
-    auto L = [](auto a) {
-      print("a = ", a, "\n");
-      foo(a);
-      return [](decltype(a) b) {
-        foo(b);
-        foo(sizeof(a) + sizeof(b));
-        return [](auto ... c) {
-          print("c = ", c ..., "\n");
-          foo(decltype(b){});
-          foo(sizeof(decltype(a)*) + sizeof(decltype(b)*));
-          return [](decltype(c) ... d) ->decltype(a) { //expected-note{{candidate}}
-            print("d = ", d ..., "\n");
-            foo(decltype(b){});
-            foo(sizeof(decltype(a)*) + sizeof(decltype(b)*));
-            return decltype(a){};
-          };
-        };
-      };
-    };
-    return L;
-  }
-auto L = test();
-auto L_test = L('4');
-auto M = L('3');
-auto M_test = M('a');
-auto N = M('x');
-auto O = N("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
-char (*np)(const char*, int, const char*, double, const char*, int) = O;
-auto NP_result = np("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
-int (*np2)(const char*, int, const char*, double, const char*, int) = O; // expected-error{{no viable conversion}}
-
-
-
-} 
-
-namespace variadic_tests_1 {
-template<class ... Ts> void print(Ts ... ts) { }
-
-template<class F, class ... Rest> using FirstType = F;
-template<class F, class ... Rest> F& FirstArg(F& f, Rest...) { return f; }
-template<class ... Ts> int fooV(Ts ... ts) {
-  auto L = [](auto ... a) -> void { 
-    auto M = [](decltype(a) ... b) -> void {  
-      auto N = [](auto c) -> void {
-        int x = 0;
-        x = sizeof...(a);        
-        x = sizeof...(b);
-        x = sizeof(c);
-      };  
-      N('a');
-      N(N);
-      N(FirstType<Ts...>{});
-    };
-    M(a...);
-    print("a = ", a..., "\n");    
-  };
-  L(L, ts...);
-  print("ts = ", ts..., "\n");
-  return 0;
-}
-
-int run2 = fooV(3.14, " ", '4', 5) + fooV("BC", 3, 2.77, 'A', float{}, short{}, unsigned{});
-
-namespace more_variadic_1 {
-
-template<class ... Ts> int fooV(Ts ... ts) {
-  auto L = [](auto ... a) { 
-    auto M = [](decltype(a) ... b) -> void {  
-      auto N = [](auto c) -> void {
-        int x = 0;
-        x = sizeof...(a);        
-        x = sizeof...(b);
-        x = sizeof(c);
-      };  
-      N('a');
-      N(N);
-      N(FirstType<Ts...>{});
-    };
-    M(a...);
-    return M;
-  };
-  auto M = L(L, ts...);
-  decltype(L(L, ts...)) (*fp)(decltype(L), decltype(ts) ...) = L;
-  void (*fp2)(decltype(L), decltype(ts) ...) = L(L, ts...);
-  
-  {
-    auto L = [](auto ... a) { 
-      auto M = [](decltype(a) ... b) {  
-        auto N = [](auto c) -> void {
-          int x = 0;
-          x = sizeof...(a);        
-          x = sizeof...(b);
-          x = sizeof(c);
-        };  
-        N('a');
-        N(N);
-        N(FirstType<Ts...>{});
-        return N;
-      };
-      M(a...);
-      return M;
-    };
-    auto M = L(L, ts...);
-    decltype(L(L, ts...)) (*fp)(decltype(L), decltype(ts) ...) = L;
-    fp(L, ts...);
-    decltype(L(L, ts...)(L, ts...)) (*fp2)(decltype(L), decltype(ts) ...) = L(L, ts...);
-    fp2 = fp(L, ts...);
-    void (*fp3)(char) = fp2(L, ts...);
-    fp3('a');
-  }
-  return 0;
-}
-
-int run2 = fooV(3.14, " ", '4', 5) + fooV("BC", 3, 2.77, 'A', float{}, short{}, unsigned{});
-
-
-} //end ns more_variadic_1
-
-} // end ns variadic_tests_1
-
-namespace at_ns_scope_within_class_member {
- struct X {
-  static void foo(double d) { } 
-  auto test() {
-    auto L = [](auto a) {
-      print("a = ", a, "\n");
-      foo(a);
-      return [](decltype(a) b) {
-        foo(b);
-        foo(sizeof(a) + sizeof(b));
-        return [](auto ... c) {
-          print("c = ", c ..., "\n");
-          foo(decltype(b){});
-          foo(sizeof(decltype(a)*) + sizeof(decltype(b)*));
-          return [](decltype(c) ... d) ->decltype(a) { //expected-note{{candidate}}
-            print("d = ", d ..., "\n");
-            foo(decltype(b){});
-            foo(sizeof(decltype(a)*) + sizeof(decltype(b)*));
-            return decltype(a){};
-          };
-        };
-      };
-    };
-    return L;
-  }
-};
-X x;
-auto L = x.test();
-auto L_test = L('4');
-auto M = L('3');
-auto M_test = M('a');
-auto N = M('x');
-auto O = N("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
-char (*np)(const char*, int, const char*, double, const char*, int) = O;
-auto NP_result = np("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
-int (*np2)(const char*, int, const char*, double, const char*, int) = O; // expected-error{{no viable conversion}}
-  
-} //end at_ns_scope_within_class_member
-
-
-namespace nested_generic_lambdas_123 {
-void test() {
-  auto L = [](auto a) -> int {
-    auto M = [](auto b, decltype(a) b2) -> int { 
-      return 1;
-    };
-    M(a, a);
-  };
-  L(3); 
-}
-template<class T> void foo(T) {
- auto L = [](auto a) { return a; }; 
-}
-template void foo(int); 
-} // end ns nested_generic_lambdas_123
-
-
-} // end ns nested_non_capturing_lambda_tests
-
-namespace PR17476 {
-struct string {
-  string(const char *__s) { }
-  string &operator+=(const string &__str) { return *this; }
-};
-
-template <class T> 
-void finalizeDefaultAtomValues() {
-  auto startEnd = [](const char * sym) -> void {
-    string start("__");
-    start += sym;
-  };
-  startEnd("preinit_array");
-}
-
-void f() { finalizeDefaultAtomValues<char>(); }
-
-} 
-
-namespace PR17476_variant {
-struct string {
-  string(const char *__s) { }
-  string &operator+=(const string &__str) { return *this; }
-};
-
-template <class T> 
-void finalizeDefaultAtomValues() {
-  auto startEnd = [](const T *sym) -> void {
-    string start("__");
-    start += sym;
-  };
-  startEnd("preinit_array");
-}
-
-void f() { finalizeDefaultAtomValues<char>(); }
-
-} 
\ No newline at end of file