Keep track of the set of array index variables we use when we
synthesize a by-copy captured array in a lambda. This information will
be needed by IR generation.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150396 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index 257a507..fcd4508 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -38,13 +38,23 @@
 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));
+                                 sizeof(Stmt*) * (Captures.size() + 1) +
+                                 ArrayIndexSize);
   
   // Copy captures.
   Capture *ToCapture = getCaptures();
@@ -62,6 +72,15 @@
   
   // 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();
+  }
 }
 
 
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index 1f8a57a..1e766ad 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -753,6 +753,8 @@
                        ArrayRef<Capture> Captures, 
                        bool ExplicitParams,
                        ArrayRef<Expr *> CaptureInits,
+                       ArrayRef<VarDecl *> ArrayElementVars,
+                       ArrayRef<unsigned> ArrayElementStarts,
                        SourceLocation ClosingBrace)
   : Expr(LambdaExprClass, T, VK_RValue, OK_Ordinary,
          T->isDependentType(), T->isDependentType(), T->isDependentType(),
@@ -765,7 +767,8 @@
   assert(CaptureInits.size() == Captures.size() && "Wrong number of arguments");
   CXXRecordDecl *Class = getLambdaClass();
   CXXRecordDecl::LambdaDefinitionData &Data = Class->getLambdaData();
-  Data.allocateExtra(Captures, CaptureInits, getCallOperator()->getBody());
+  Data.allocateExtra(Captures, CaptureInits, ArrayElementVars, 
+                     ArrayElementStarts, getCallOperator()->getBody());
   
   // FIXME: Propagate "has unexpanded parameter pack" bit.
 }
@@ -777,6 +780,8 @@
                                ArrayRef<Capture> Captures, 
                                bool ExplicitParams,
                                ArrayRef<Expr *> CaptureInits,
+                               ArrayRef<VarDecl *> ArrayElementVars,
+                               ArrayRef<unsigned> ArrayElementStarts,
                                SourceLocation ClosingBrace) {
   // Determine the type of the expression (i.e., the type of the
   // function object we're creating).
@@ -784,6 +789,7 @@
 
   return new (Context) LambdaExpr(T, IntroducerRange, CaptureDefault, 
                                   Captures, ExplicitParams, CaptureInits,
+                                  ArrayElementVars, ArrayElementStarts,
                                   ClosingBrace);
 }
 
@@ -826,6 +832,19 @@
   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?");
+  
+  unsigned Index = Iter - capture_init_begin();
+  assert(Index < Data.NumCaptures && "Capture index out-of-range");
+  VarDecl **IndexVars = Data.getArrayIndexVars();
+  unsigned *IndexStarts = Data.getArrayIndexStarts();
+  return ArrayRef<VarDecl *>(IndexVars + IndexStarts[Index],
+                             IndexVars + IndexStarts[Index + 1]);
+}
+
 CXXRecordDecl *LambdaExpr::getLambdaClass() const {
   return getType()->getAsCXXRecordDecl();
 }