Split the storage of lambda information between the LambdaExpr and the
CXXRecordDecl in a way that actually makes some sense:
  - LambdaExpr contains all of the information for initializing the
  lambda object, including the capture initializers and associated
  array index variables.
  - CXXRecordDecl's LambdaDefinitionData contains the captures, which
  are needed to understand the captured variable references in the
  body of the lambda.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150401 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index fcd4508..5b9ab4f 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -35,55 +35,6 @@
   return new (Mem) AccessSpecDecl(EmptyShell());
 }
 
-void CXXRecordDecl::LambdaDefinitionData::allocateExtra(
-       ArrayRef<LambdaExpr::Capture> Captures,
-       ArrayRef<Expr *> CaptureInits,
-       ArrayRef<VarDecl *> ArrayIndexVars,
-       ArrayRef<unsigned> ArrayIndexStarts,
-       Stmt *Body) {
-  NumCaptures = Captures.size();
-  NumExplicitCaptures = 0;
-  
-  ASTContext &Context = Definition->getASTContext();
-  unsigned ArrayIndexSize = 0;
-  if (ArrayIndexVars.size() > 0) {
-    HasArrayIndexVars = true;
-    ArrayIndexSize = sizeof(unsigned) * (Captures.size() + 1)
-                   + sizeof(VarDecl *) * ArrayIndexVars.size();
-  }
-  
-  this->Extra = Context.Allocate(sizeof(Capture) * Captures.size() +
-                                 sizeof(Stmt*) * (Captures.size() + 1) +
-                                 ArrayIndexSize);
-  
-  // Copy captures.
-  Capture *ToCapture = getCaptures();
-  for (unsigned I = 0, N = Captures.size(); I != N; ++I) {
-    if (Captures[I].isExplicit())
-      ++NumExplicitCaptures;
-    
-    *ToCapture++ = Captures[I];
-  }
-  
-  // Copy initialization expressions for the non-static data members.
-  Stmt **Stored = getStoredStmts();
-  for (unsigned I = 0, N = CaptureInits.size(); I != N; ++I)
-    *Stored++ = CaptureInits[I];
-  
-  // Copy the body of the lambda.
-  *Stored++ = Body;
-  
-  if (ArrayIndexVars.size() > 0) {
-    assert(ArrayIndexStarts.size() == Captures.size());
-    memcpy(getArrayIndexVars(), ArrayIndexVars.data(),
-           sizeof(VarDecl *) * ArrayIndexVars.size());
-    memcpy(getArrayIndexStarts(), ArrayIndexStarts.data(), 
-           sizeof(unsigned) * Captures.size());
-    getArrayIndexStarts()[Captures.size()] = ArrayIndexVars.size();
-  }
-}
-
-
 CXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl *D)
   : UserDeclaredConstructor(false), UserDeclaredCopyConstructor(false),
     UserDeclaredMoveConstructor(false), UserDeclaredCopyAssignment(false),
@@ -1035,8 +986,7 @@
 
   LambdaDefinitionData &Lambda = getLambdaData();
   RecordDecl::field_iterator Field = field_begin();
-  for (LambdaExpr::Capture *C = Lambda.getCaptures(), 
-                        *CEnd = C + Lambda.NumCaptures;
+  for (LambdaExpr::Capture *C = Lambda.Captures, *CEnd = C + Lambda.NumCaptures;
        C != CEnd; ++C, ++Field) {
     if (C->capturesThis()) {
       ThisCapture = *Field;
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index 1e766ad..4962bf4 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -753,13 +753,14 @@
                        ArrayRef<Capture> Captures, 
                        bool ExplicitParams,
                        ArrayRef<Expr *> CaptureInits,
-                       ArrayRef<VarDecl *> ArrayElementVars,
-                       ArrayRef<unsigned> ArrayElementStarts,
+                       ArrayRef<VarDecl *> ArrayIndexVars,
+                       ArrayRef<unsigned> ArrayIndexStarts,
                        SourceLocation ClosingBrace)
   : Expr(LambdaExprClass, T, VK_RValue, OK_Ordinary,
          T->isDependentType(), T->isDependentType(), T->isDependentType(),
          /*ContainsUnexpandedParameterPack=*/false),
     IntroducerRange(IntroducerRange),
+    NumCaptures(Captures.size()),
     CaptureDefault(CaptureDefault),
     ExplicitParams(ExplicitParams),
     ClosingBrace(ClosingBrace)
@@ -767,10 +768,40 @@
   assert(CaptureInits.size() == Captures.size() && "Wrong number of arguments");
   CXXRecordDecl *Class = getLambdaClass();
   CXXRecordDecl::LambdaDefinitionData &Data = Class->getLambdaData();
-  Data.allocateExtra(Captures, CaptureInits, ArrayElementVars, 
-                     ArrayElementStarts, getCallOperator()->getBody());
   
   // FIXME: Propagate "has unexpanded parameter pack" bit.
+  
+  // Copy captures.
+  ASTContext &Context = Class->getASTContext();
+  Data.NumCaptures = NumCaptures;
+  Data.NumExplicitCaptures = 0;
+  Data.Captures = (Capture *)Context.Allocate(sizeof(Capture) * NumCaptures);
+  Capture *ToCapture = Data.Captures;
+  for (unsigned I = 0, N = Captures.size(); I != N; ++I) {
+    if (Captures[I].isExplicit())
+      ++Data.NumExplicitCaptures;
+    
+    *ToCapture++ = Captures[I];
+  }
+ 
+  // Copy initialization expressions for the non-static data members.
+  Stmt **Stored = getStoredStmts();
+  for (unsigned I = 0, N = CaptureInits.size(); I != N; ++I)
+    *Stored++ = CaptureInits[I];
+  
+  // Copy the body of the lambda.
+  *Stored++ = getCallOperator()->getBody();
+
+  // Copy the array index variables, if any.
+  HasArrayIndexVars = !ArrayIndexVars.empty();
+  if (HasArrayIndexVars) {
+    assert(ArrayIndexStarts.size() == NumCaptures);
+    memcpy(getArrayIndexVars(), ArrayIndexVars.data(),
+           sizeof(VarDecl *) * ArrayIndexVars.size());
+    memcpy(getArrayIndexStarts(), ArrayIndexStarts.data(), 
+           sizeof(unsigned) * Captures.size());
+    getArrayIndexStarts()[Captures.size()] = ArrayIndexVars.size();
+  }  
 }
 
 LambdaExpr *LambdaExpr::Create(ASTContext &Context, 
@@ -780,27 +811,30 @@
                                ArrayRef<Capture> Captures, 
                                bool ExplicitParams,
                                ArrayRef<Expr *> CaptureInits,
-                               ArrayRef<VarDecl *> ArrayElementVars,
-                               ArrayRef<unsigned> ArrayElementStarts,
+                               ArrayRef<VarDecl *> ArrayIndexVars,
+                               ArrayRef<unsigned> ArrayIndexStarts,
                                SourceLocation ClosingBrace) {
   // Determine the type of the expression (i.e., the type of the
   // function object we're creating).
   QualType T = Context.getTypeDeclType(Class);
 
-  return new (Context) LambdaExpr(T, IntroducerRange, CaptureDefault, 
-                                  Captures, ExplicitParams, CaptureInits,
-                                  ArrayElementVars, ArrayElementStarts,
-                                  ClosingBrace);
+  unsigned Size = sizeof(LambdaExpr) + sizeof(Stmt *) * (Captures.size() + 1);
+  if (!ArrayIndexVars.empty())
+    Size += sizeof(VarDecl *) * ArrayIndexVars.size()
+          + sizeof(unsigned) * (Captures.size() + 1);
+  void *Mem = Context.Allocate(Size);
+  return new (Mem) LambdaExpr(T, IntroducerRange, CaptureDefault, 
+                              Captures, ExplicitParams, CaptureInits,
+                              ArrayIndexVars, ArrayIndexStarts,
+                              ClosingBrace);
 }
 
 LambdaExpr::capture_iterator LambdaExpr::capture_begin() const {
-  return getLambdaClass()->getLambdaData().getCaptures();
+  return getLambdaClass()->getLambdaData().Captures;
 }
 
 LambdaExpr::capture_iterator LambdaExpr::capture_end() const {
-  struct CXXRecordDecl::LambdaDefinitionData &Data
-    = getLambdaClass()->getLambdaData();
-  return Data.getCaptures() + Data.NumCaptures;
+  return capture_begin() + NumCaptures;
 }
 
 LambdaExpr::capture_iterator LambdaExpr::explicit_capture_begin() const {
@@ -810,7 +844,7 @@
 LambdaExpr::capture_iterator LambdaExpr::explicit_capture_end() const {
   struct CXXRecordDecl::LambdaDefinitionData &Data
     = getLambdaClass()->getLambdaData();
-  return Data.getCaptures() + Data.NumExplicitCaptures;
+  return Data.Captures + Data.NumExplicitCaptures;
 }
 
 LambdaExpr::capture_iterator LambdaExpr::implicit_capture_begin() const {
@@ -821,26 +855,15 @@
   return capture_end();
 }
 
-LambdaExpr::capture_init_iterator LambdaExpr::capture_init_begin() const {
-  return reinterpret_cast<Expr **>(
-           getLambdaClass()->getLambdaData().getStoredStmts());
-}
-
-LambdaExpr::capture_init_iterator LambdaExpr::capture_init_end() const {
-  struct CXXRecordDecl::LambdaDefinitionData &Data
-    = getLambdaClass()->getLambdaData();
-  return reinterpret_cast<Expr **>(Data.getStoredStmts() + Data.NumCaptures);
-}
-
 ArrayRef<VarDecl *> 
 LambdaExpr::getCaptureInitIndexVars(capture_init_iterator Iter) const {
   CXXRecordDecl::LambdaDefinitionData &Data = getLambdaClass()->getLambdaData();
-  assert(Data.HasArrayIndexVars && "No array index-var data?");
+  assert(HasArrayIndexVars && "No array index-var data?");
   
   unsigned Index = Iter - capture_init_begin();
   assert(Index < Data.NumCaptures && "Capture index out-of-range");
-  VarDecl **IndexVars = Data.getArrayIndexVars();
-  unsigned *IndexStarts = Data.getArrayIndexStarts();
+  VarDecl **IndexVars = getArrayIndexVars();
+  unsigned *IndexStarts = getArrayIndexStarts();
   return ArrayRef<VarDecl *>(IndexVars + IndexStarts[Index],
                              IndexVars + IndexStarts[Index + 1]);
 }
@@ -860,22 +883,10 @@
   return Result;
 }
 
-/// \brief Retrieve the body of the lambda.
-CompoundStmt *LambdaExpr::getBody() const {
-  return cast<CompoundStmt>(*capture_init_end());
-}
-
 bool LambdaExpr::isMutable() const {
   return (getCallOperator()->getTypeQualifiers() & Qualifiers::Const) == 0;
 }
 
-Stmt::child_range LambdaExpr::children() {
-  struct CXXRecordDecl::LambdaDefinitionData &Data
-    = getLambdaClass()->getLambdaData();
-  return child_range(Data.getStoredStmts(), 
-                     Data.getStoredStmts() + Data.NumCaptures + 1);
-}
-
 ExprWithCleanups::ExprWithCleanups(Expr *subexpr,
                                    ArrayRef<CleanupObject> objects)
   : Expr(ExprWithCleanupsClass, subexpr->getType(),