Index: include/clang/Basic/StmtNodes.td
===================================================================
--- include/clang/Basic/StmtNodes.td	(revision 179677)
+++ include/clang/Basic/StmtNodes.td	(working copy)
@@ -170,6 +170,7 @@
 def SEHExceptStmt : Stmt;
 def SEHFinallyStmt : Stmt;
 def MSDependentExistsStmt : Stmt;
+def MSDependentForEachStmt : Stmt;
 
 // OpenCL Extensions.
 def AsTypeExpr : DStmt<Expr>;
Index: include/clang/Parse/Parser.h
===================================================================
--- include/clang/Parse/Parser.h	(revision 179677)
+++ include/clang/Parse/Parser.h	(working copy)
@@ -1579,12 +1579,14 @@
                                         SourceLocation &DeclEnd,
                                         ParsedAttributesWithRange &attrs,
                                         bool RequireSemi,
-                                        ForRangeInit *FRI = 0);
+                                        ForRangeInit *FRI = 0,
+                                        bool IsMsForEach = false);
   bool MightBeDeclarator(unsigned Context);
   DeclGroupPtrTy ParseDeclGroup(ParsingDeclSpec &DS, unsigned Context,
                                 bool AllowFunctionDefinitions,
                                 SourceLocation *DeclEnd = 0,
-                                ForRangeInit *FRI = 0);
+                                ForRangeInit *FRI = 0,
+                                bool IsMsForEach = false);
   Decl *ParseDeclarationAfterDeclarator(Declarator &D,
                const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo());
   bool ParseAsmAttributesAfterDeclarator(Declarator &D);
Index: include/clang/Serialization/ASTBitCodes.h
===================================================================
--- include/clang/Serialization/ASTBitCodes.h	(revision 179677)
+++ include/clang/Serialization/ASTBitCodes.h	(working copy)
@@ -1312,6 +1312,7 @@
       STMT_SEH_EXCEPT,            // SEHExceptStmt
       STMT_SEH_FINALLY,           // SEHFinallyStmt
       STMT_SEH_TRY,               // SEHTryStmt
+      STMT_MS_DEPENDENT_FOR_EACH,
       
       // ARC
       EXPR_OBJC_BRIDGED_CAST,     // ObjCBridgedCastExpr
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h	(revision 179677)
+++ include/clang/Sema/Sema.h	(working copy)
@@ -2744,6 +2744,7 @@
                                         Stmt *First, Expr *collection,
                                         SourceLocation RParenLoc);
   StmtResult FinishObjCForCollectionStmt(Stmt *ForCollection, Stmt *Body);
+  StmtResult FinishMSForEachStmt(Stmt *ForCollection, Stmt *Body);
 
   enum BuildForRangeKind {
     /// Initial building of a for-range statement.
@@ -2756,6 +2757,8 @@
     BFRK_Check
   };
 
+  StmtResult ActOnMSForEachStmt(SourceLocation ForLoc, Stmt *RangeDecl,
+                                Expr *Collection, SourceLocation RParenLoc);
   StmtResult ActOnCXXForRangeStmt(SourceLocation ForLoc, Stmt *LoopVar,
                                   SourceLocation ColonLoc, Expr *Collection,
                                   SourceLocation RParenLoc,
Index: include/clang/AST/StmtCXX.h
===================================================================
--- include/clang/AST/StmtCXX.h	(revision 179677)
+++ include/clang/AST/StmtCXX.h	(working copy)
@@ -287,6 +287,45 @@
   }
 };
 
+class MSDependentForEachStmt : public Stmt {
+  enum {RANGE_DECL, COLLECTION, BODY, END};
+  Stmt *Children[END];
+  SourceLocation ForLoc, RParenLoc;
+    
+public:
+  MSDependentForEachStmt(Stmt *RangeDecl, Expr *Collection, Stmt *Body,
+                         SourceLocation ForLoc, SourceLocation RParenLoc)
+  : Stmt(MSDependentForEachStmtClass), ForLoc(ForLoc), RParenLoc(RParenLoc) {
+    Children[RANGE_DECL] = RangeDecl;
+    Children[COLLECTION] = Collection;
+    Children[BODY] = Body;
+  }
+  MSDependentForEachStmt(EmptyShell Empty)
+  : Stmt(MSDependentForEachStmtClass, Empty) { }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return ForLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY {
+    return Children[BODY]->getLocEnd();
+  }
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == MSDependentForEachStmtClass;
+  }
+  child_range children() {
+    return child_range(&Children[0], &Children[END]);
+  }
+    
+  Stmt* getRangeDecl() { return Children[RANGE_DECL]; }
+  void setRangeDecl(Stmt *S) { Children[RANGE_DECL] = S; }
+  Expr* getCollection() { return (Expr*)(Children[COLLECTION]); }
+  void setCollection(Expr *E) { Children[COLLECTION] = E; }
+  Stmt* getBody() { return Children[BODY]; }
+  void setBody(Stmt *S) { Children[BODY] = S; }
+  SourceLocation getForLoc() { return ForLoc; }
+  void setForLoc(SourceLocation Loc) { ForLoc = Loc; }
+  SourceLocation getRParenLoc() { return RParenLoc; }
+  void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; }
+};
+
 }  // end namespace clang
 
 #endif
Index: include/clang/AST/RecursiveASTVisitor.h
===================================================================
--- include/clang/AST/RecursiveASTVisitor.h	(revision 179677)
+++ include/clang/AST/RecursiveASTVisitor.h	(working copy)
@@ -1925,6 +1925,7 @@
 DEF_TRAVERSE_STMT(SwitchStmt, { })
 DEF_TRAVERSE_STMT(WhileStmt, { })
 
+DEF_TRAVERSE_STMT(MSDependentForEachStmt, { })
 
 DEF_TRAVERSE_STMT(CXXDependentScopeMemberExpr, {
     TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
Index: tools/libclang/RecursiveASTVisitor.h
===================================================================
--- tools/libclang/RecursiveASTVisitor.h	(revision 179677)
+++ tools/libclang/RecursiveASTVisitor.h	(working copy)
@@ -1845,6 +1845,7 @@
     TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
     TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
 })
+DEF_TRAVERSE_STMT(MSDependentForEachStmt, { })
 DEF_TRAVERSE_STMT(ReturnStmt, { })
 DEF_TRAVERSE_STMT(SwitchStmt, { })
 DEF_TRAVERSE_STMT(WhileStmt, { })
Index: lib/StaticAnalyzer/Core/ExprEngine.cpp
===================================================================
--- lib/StaticAnalyzer/Core/ExprEngine.cpp	(revision 179677)
+++ lib/StaticAnalyzer/Core/ExprEngine.cpp	(working copy)
@@ -656,6 +656,7 @@
     case Stmt::SwitchStmtClass:
     case Stmt::WhileStmtClass:
     case Expr::MSDependentExistsStmtClass:
+    case Expr::MSDependentForEachStmtClass:
     case Stmt::CapturedStmtClass:
       llvm_unreachable("Stmt should not be in analyzer evaluation loop");
 
Index: lib/CodeGen/CGStmt.cpp
===================================================================
--- lib/CodeGen/CGStmt.cpp	(revision 179677)
+++ lib/CodeGen/CGStmt.cpp	(working copy)
@@ -73,6 +73,7 @@
   case Stmt::CXXCatchStmtClass:
   case Stmt::SEHExceptStmtClass:
   case Stmt::SEHFinallyStmtClass:
+  case Stmt::MSDependentForEachStmtClass:
   case Stmt::MSDependentExistsStmtClass:
     llvm_unreachable("invalid statement class to emit generically");
   case Stmt::NullStmtClass:
Index: lib/Parse/ParseStmt.cpp
===================================================================
--- lib/Parse/ParseStmt.cpp	(revision 179677)
+++ lib/Parse/ParseStmt.cpp	(working copy)
@@ -1325,7 +1325,11 @@
   assert(Tok.is(tok::kw_for) && "Not a for stmt!");
   SourceLocation ForLoc = ConsumeToken();  // eat the 'for'.
 
-  if (Tok.isNot(tok::l_paren)) {
+  bool IsMsForEach = false;
+  if (Tok.is(tok::identifier) && Tok.getIdentifierInfo()->getName() == "each") {
+    IsMsForEach = true;
+    ConsumeAnyToken();
+  } else if (Tok.isNot(tok::l_paren)) {
     Diag(Tok, diag::err_expected_lparen_after) << "for";
     SkipUntil(tok::semi);
     return StmtError();
@@ -1402,7 +1406,8 @@
     DeclGroupPtrTy DG = ParseSimpleDeclaration(Stmts, Declarator::ForContext,
                                                DeclEnd, attrs, false,
                                                MightBeForRangeStmt ?
-                                                 &ForRangeInit : 0);
+                                                 &ForRangeInit : 0,
+                                               IsMsForEach);
     FirstPart = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation());
 
     if (ForRangeInit.ParsedForRangeDecl()) {
@@ -1442,7 +1447,7 @@
 
     if (Tok.is(tok::semi)) {
       ConsumeToken();
-    } else if (ForEach) {
+    } else if (ForEach || IsMsForEach) {
       ConsumeToken(); // consume 'in'
 
       if (Tok.is(tok::code_completion)) {
@@ -1469,7 +1474,7 @@
       }
     }
   }
-  if (!ForEach && !ForRange) {
+  if (!IsMsForEach && !ForEach && !ForRange) {
     assert(!SecondPart.get() && "Shouldn't have a second expression yet.");
     // Parse the second part of the for specifier.
     if (Tok.is(tok::semi)) {  // for (...;;
@@ -1519,7 +1524,12 @@
   StmtResult ForRangeStmt;
   StmtResult ForEachStmt;
 
-  if (ForRange) {
+  if (IsMsForEach) {
+    ForEachStmt = Actions.ActOnMSForEachStmt(ForLoc,
+                                             FirstPart.take(),
+                                             ForRangeInit.RangeExpr.take(),
+                                             T.getCloseLocation());
+  } else if (ForRange) {
     ForRangeStmt = Actions.ActOnCXXForRangeStmt(ForLoc, FirstPart.take(),
                                                 ForRangeInit.ColonLoc,
                                                 ForRangeInit.RangeExpr.get(),
@@ -1562,6 +1572,9 @@
   if (Body.isInvalid())
     return StmtError();
 
+  if (IsMsForEach)
+    return Actions.FinishMSForEachStmt(ForEachStmt.take(), Body.take());
+
   if (ForEach)
    return Actions.FinishObjCForCollectionStmt(ForEachStmt.take(),
                                               Body.take());
Index: lib/Parse/ParseDecl.cpp
===================================================================
--- lib/Parse/ParseDecl.cpp	(revision 179677)
+++ lib/Parse/ParseDecl.cpp	(working copy)
@@ -1397,7 +1397,8 @@
 Parser::ParseSimpleDeclaration(StmtVector &Stmts, unsigned Context,
                                SourceLocation &DeclEnd,
                                ParsedAttributesWithRange &Attrs,
-                               bool RequireSemi, ForRangeInit *FRI) {
+                               bool RequireSemi, ForRangeInit *FRI,
+                               bool IsMsForEach) {
   // Parse the common declaration-specifiers piece.
   ParsingDeclSpec DS(*this);
 
@@ -1417,7 +1418,8 @@
   }
 
   DS.takeAttributesFrom(Attrs);
-  return ParseDeclGroup(DS, Context, /*FunctionDefs=*/ false, &DeclEnd, FRI);
+  return ParseDeclGroup(DS, Context, /*FunctionDefs=*/ false, &DeclEnd, FRI,
+                        IsMsForEach);
 }
 
 /// Returns true if this might be the start of a declarator, or a common typo
@@ -1572,7 +1574,8 @@
                                               unsigned Context,
                                               bool AllowFunctionDefinitions,
                                               SourceLocation *DeclEnd,
-                                              ForRangeInit *FRI) {
+                                              ForRangeInit *FRI,
+                                              bool IsMsForEach) {
   // Parse the first declarator.
   ParsingDeclarator D(*this, DS, static_cast<Declarator::TheContext>(Context));
   ParseDeclarator(D);
@@ -1639,9 +1642,13 @@
   //
   // Handle the Objective-C for-in loop variable similarly, although we
   // don't need to parse the container in advance.
-  if (FRI && (Tok.is(tok::colon) || isTokIdentifier_in())) {
+  if (FRI && (Tok.is(tok::colon) || isTokIdentifier_in()
+      || (IsMsForEach && Tok.is(tok::identifier)
+         && (Tok.getIdentifierInfo()->getName() == "in")))) {
     bool IsForRangeLoop = false;
-    if (Tok.is(tok::colon)) {
+    if ((!IsMsForEach && Tok.is(tok::colon))
+        || (IsMsForEach && Tok.is(tok::identifier)
+           && (Tok.getIdentifierInfo()->getName() == "in"))) {
       IsForRangeLoop = true;
       FRI->ColonLoc = ConsumeToken();
       if (Tok.is(tok::l_brace))
Index: lib/Serialization/ASTWriterStmt.cpp
===================================================================
--- lib/Serialization/ASTWriterStmt.cpp	(revision 179677)
+++ lib/Serialization/ASTWriterStmt.cpp	(working copy)
@@ -1062,6 +1062,16 @@
   Code = serialization::STMT_MS_DEPENDENT_EXISTS;
 }
 
+void ASTStmtWriter::VisitMSDependentForEachStmt(MSDependentForEachStmt *S) {
+  VisitStmt(S);
+  Writer.AddSourceLocation(S->getForLoc(), Record);
+  Writer.AddSourceLocation(S->getRParenLoc(), Record);
+  Writer.AddStmt(S->getRangeDecl());
+  Writer.AddStmt(S->getCollection());
+  Writer.AddStmt(S->getBody());
+  Code = serialization::STMT_MS_DEPENDENT_FOR_EACH;
+}
+
 void ASTStmtWriter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
   VisitCallExpr(E);
   Record.push_back(E->getOperator());
Index: lib/Serialization/ASTReaderStmt.cpp
===================================================================
--- lib/Serialization/ASTReaderStmt.cpp	(revision 179677)
+++ lib/Serialization/ASTReaderStmt.cpp	(working copy)
@@ -1090,6 +1090,15 @@
   S->SubStmt = Reader.ReadSubStmt();
 }
 
+void ASTStmtReader::VisitMSDependentForEachStmt(MSDependentForEachStmt *S) {
+  VisitStmt(S);
+  S->setForLoc(ReadSourceLocation(Record, Idx));
+  S->setRParenLoc(ReadSourceLocation(Record, Idx));
+  S->setRangeDecl(Reader.ReadSubStmt());
+  S->setCollection(Reader.ReadSubExpr());
+  S->setBody(Reader.ReadSubStmt());
+}
+
 void ASTStmtReader::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
   VisitCallExpr(E);
   E->Operator = (OverloadedOperatorKind)Record[Idx++];
@@ -2023,6 +2032,10 @@
       S = new (Context) CXXForRangeStmt(Empty);
       break;
 
+    case STMT_MS_DEPENDENT_FOR_EACH:
+      S = new (Context) MSDependentForEachStmt(Empty);
+      break;
+
     case STMT_MS_DEPENDENT_EXISTS:
       S = new (Context) MSDependentExistsStmt(SourceLocation(), true,
                                               NestedNameSpecifierLoc(),
Index: lib/AST/StmtPrinter.cpp
===================================================================
--- lib/AST/StmtPrinter.cpp	(revision 179677)
+++ lib/AST/StmtPrinter.cpp	(working copy)
@@ -321,6 +321,16 @@
   }
 }
 
+void StmtPrinter::VisitMSDependentForEachStmt(MSDependentForEachStmt *Node) {
+  Indent() << "for each (";
+  PrintStmt(Node->getRangeDecl());
+  OS << " in ";
+  PrintExpr(Node->getCollection());
+  OS << ") {\n";
+  PrintStmt(Node->getBody());
+  Indent() << "}\n";
+}
+
 void StmtPrinter::VisitCXXForRangeStmt(CXXForRangeStmt *Node) {
   Indent() << "for (";
   PrintingPolicy SubPolicy(Policy);
Index: lib/AST/StmtProfile.cpp
===================================================================
--- lib/AST/StmtProfile.cpp	(revision 179677)
+++ lib/AST/StmtProfile.cpp	(working copy)
@@ -196,6 +196,11 @@
   VisitStmt(S);
 }
 
+void
+StmtProfiler::VisitMSDependentForEachStmt(const MSDependentForEachStmt *S) {
+  VisitStmt(S);
+}
+
 void StmtProfiler::VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
   VisitStmt(S);
   ID.AddBoolean(S->isIfExists());
Index: lib/Sema/SemaPseudoObject.cpp
===================================================================
--- lib/Sema/SemaPseudoObject.cpp	(revision 179677)
+++ lib/Sema/SemaPseudoObject.cpp	(working copy)
@@ -312,6 +312,9 @@
    Expr *rebuildAndCaptureObject(Expr *);
    ExprResult buildGet();
    ExprResult buildSet(Expr *op, SourceLocation, bool);
+   ExprResult buildIncDecOperation(Scope *Sc, SourceLocation opLoc,
+                                   UnaryOperatorKind opcode,
+                                   Expr *op);
  };
 }
 
@@ -1424,6 +1427,21 @@
                          op->getSourceRange().getEnd());
 }
 
+ExprResult
+MSPropertyOpBuilder::buildIncDecOperation(Scope *Sc, SourceLocation opLoc,
+                                          UnaryOperatorKind opcode,
+                                          Expr *op) {
+  ExprResult result = buildGet();
+  if (result.isInvalid()) return ExprError();
+
+  QualType resultType = result.get()->getType();
+  if (resultType->isDependentType())
+    return new (S.Context) UnaryOperator(op, opcode, S.Context.DependentTy,
+                                         VK_RValue, OK_Ordinary, opLoc);
+
+  return PseudoOpBuilder::buildIncDecOperation(Sc, opLoc, opcode, op);
+}
+
 //===----------------------------------------------------------------------===//
 //  General Sema routines.
 //===----------------------------------------------------------------------===//
Index: lib/Sema/TreeTransform.h
===================================================================
--- lib/Sema/TreeTransform.h	(revision 179677)
+++ lib/Sema/TreeTransform.h	(working copy)
@@ -6029,6 +6029,20 @@
 }
 
 template<typename Derived>
+StmtResult
+TreeTransform<Derived>::TransformMSDependentForEachStmt(
+  MSDependentForEachStmt *S) {
+  StmtResult RangeDecl = getDerived().TransformStmt(S->getRangeDecl());
+  ExprResult Collection = getDerived().TransformExpr(S->getCollection());
+  StmtResult newStmt =
+    getSema().ActOnMSForEachStmt(S->getSourceRange().getBegin(),
+                                 RangeDecl.get(), Collection.get(),
+                                 S->getSourceRange().getEnd());
+  StmtResult Block = getDerived().TransformStmt(S->getBody());
+  return getSema().FinishMSForEachStmt(newStmt.get(), Block.get());
+}
+
+template<typename Derived>
 ExprResult
 TreeTransform<Derived>::TransformMSPropertyRefExpr(MSPropertyRefExpr *E) {
   NestedNameSpecifierLoc QualifierLoc;
Index: lib/Sema/SemaStmt.cpp
===================================================================
--- lib/Sema/SemaStmt.cpp	(revision 179677)
+++ lib/Sema/SemaStmt.cpp	(working copy)
@@ -3025,3 +3025,146 @@
 
   return Owned(Res);
 }
+
+///  {
+///    auto&& __enumerator = collection.GetEnumerator();
+///    while (__enumerator.MoveNext()) {
+///      for-range-declaration = __enumerator.GetCurrent();
+///      statement
+///    }
+///  }
+StmtResult
+Sema::ActOnMSForEachStmt(SourceLocation ForLoc, Stmt *RangeDecl,
+                         Expr *Collection, SourceLocation RParenLoc) {
+  DeclStmt *DS = dyn_cast<DeclStmt>(RangeDecl);
+  assert(DS && "first part of for each not a decl stmt");
+  assert(DS->isSingleDecl());
+  assert(!DS->getSingleDecl()->isInvalidDecl());
+  
+  if (Collection->getType()->getAsPlaceholderType()
+      && (Collection->getType()->getAsPlaceholderType()->getKind()
+          == BuiltinType::PseudoObject))
+    Collection = checkPseudoObjectRValue(Collection).take();
+  
+  bool IsDependent = Collection->getType()->isDependentType();
+  if (!IsDependent)
+  {
+    // auto&& __enumerator = collection.GetEnumerator();
+    DeclarationNameInfo GetEnumeratorNameInfo(
+      &getPreprocessor().getIdentifierTable().get("GetEnumerator"),
+      RangeDecl->getLocStart());
+    LookupResult GetEnumeratorLookup(*this, GetEnumeratorNameInfo,
+                                     Sema::LookupMemberName);
+    CXXRecordDecl *D = Collection->getType()->getAsCXXRecordDecl();
+    assert(D);
+    LookupQualifiedName(GetEnumeratorLookup, D);
+    assert(!GetEnumeratorLookup.empty());
+    Scope *S = getCurScope();
+    ExprResult EnumeratorMemberRef =
+      BuildMemberReferenceExpr(Collection, Collection->getType(),
+                               SourceLocation(), false, CXXScopeSpec(),
+                               RangeDecl->getLocStart(), 0,
+                               GetEnumeratorLookup, 0);
+    ExprResult EnumeratorValue = ActOnCallExpr(S, EnumeratorMemberRef.get(),
+                                               ForLoc, MultiExprArg(),
+                                               RParenLoc, 0);
+    assert(!EnumeratorValue.isInvalid());
+    VarDecl *EnumeratorVar =
+      BuildForRangeVarDecl(*this, RangeDecl->getLocStart(),
+                           Context.getAutoRRefDeductType(), "__enumerator");
+    Expr *Enum = EnumeratorValue.take();
+    assert(!FinishForRangeVarDecl(*this, EnumeratorVar, Enum,
+                                  RangeDecl->getLocStart(),
+                                  diag::err_for_range_deduction_failure));
+  
+    // __enumerator.MoveNext()
+    ExprResult EnumeratorRef =
+      BuildDeclRefExpr(EnumeratorVar,
+                       EnumeratorVar->getType().getNonReferenceType(),
+                       VK_LValue, RangeDecl->getLocStart());
+    assert(!EnumeratorRef.isInvalid());
+    Expr *Enumerator = EnumeratorRef.take();
+    DeclarationNameInfo MoveNextNameInfo(
+      &getPreprocessor().getIdentifierTable().get("MoveNext"),
+      RangeDecl->getLocStart());
+    LookupResult MoveNextLookup(*this, MoveNextNameInfo,
+                                Sema::LookupMemberName);
+    if (Enum->getType()->isDependentType()) {
+      IsDependent = true;
+    } else {
+      LookupQualifiedName(MoveNextLookup, Enum->getType()->getAsCXXRecordDecl());
+      assert(!MoveNextLookup.empty());
+      ExprResult MoveNextMemberRef =
+        BuildMemberReferenceExpr(Enumerator, Enumerator->getType(),
+                                 ForLoc, false, CXXScopeSpec(), RParenLoc, 0,
+                                 MoveNextLookup, 0);
+      ExprResult MoveNextValue =
+        ActOnCallExpr(S, MoveNextMemberRef.get(), RangeDecl->getLocStart(),
+                      MultiExprArg(), RangeDecl->getLocStart(), 0);
+      assert(!MoveNextValue.isInvalid());
+      ExprResult MoveNext = ActOnFinishFullExpr(ActOnBooleanCondition(S,
+        SourceLocation(), MoveNextValue.take()).take());
+      assert(!MoveNext.isInvalid());
+  
+      // for-range-declaration = __enumerator.GetCurrent();
+      DeclarationNameInfo CurrentNameInfo(
+        &getPreprocessor().getIdentifierTable().get("GetCurrent"),
+        RangeDecl->getLocStart());
+      LookupResult CurrentLookup(*this, CurrentNameInfo,
+                                 Sema::LookupMemberName);
+      LookupQualifiedName(CurrentLookup, Enum->getType()->getAsCXXRecordDecl());
+      assert(!CurrentLookup.empty());
+      ExprResult CurrentMemberRef =
+        BuildMemberReferenceExpr(Enumerator, Enumerator->getType(),
+                                 ForLoc, false, CXXScopeSpec(), RParenLoc, 0,
+                                 CurrentLookup, 0);
+      ExprResult CurrentValue = ActOnCallExpr(S, CurrentMemberRef.get(),
+                                              ForLoc, MultiExprArg(),
+                                              RParenLoc, 0);
+      assert(!CurrentValue.isInvalid());
+      AddInitializerToDecl(DS->getSingleDecl(), CurrentValue.take(),
+                           false, true);
+  
+      // Build the while loop
+      Stmt *Stmts[2] = {DS, NULL};
+      Stmt *RealLoopBody = new (Context) CompoundStmt(getASTContext(), Stmts,
+                                                      ForLoc, ForLoc);
+      FullExprArg Arg(MoveNext.take());
+      StmtResult WhileStmt = ActOnWhileStmt(ForLoc, Arg, 0, RealLoopBody);
+  
+      Stmt *EnumeratorDeclStmt =
+        new (Context) DeclStmt(DeclGroupRef(EnumeratorVar), ForLoc, ForLoc);
+      Stmt *StmtsFinal[2] = {EnumeratorDeclStmt, WhileStmt.take()};
+      Stmt *Result =
+        new (Context) CompoundStmt(getASTContext(), StmtsFinal,
+                                   ForLoc, ForLoc);
+      return Result;
+    }
+  }
+  assert(IsDependent);
+  return new (Context) MSDependentForEachStmt(RangeDecl, Collection, 0,
+                                              ForLoc, RParenLoc);
+}
+
+StmtResult Sema::FinishMSForEachStmt(Stmt *S, Stmt *B)
+{
+  assert(S && B);
+  if (isa<CompoundStmt>(S)) {
+    clang::CompoundStmt *CS = dyn_cast<clang::CompoundStmt>(S);
+    WhileStmt *WS = dyn_cast<WhileStmt>(CS->body_begin()[1]);
+    assert(WS);
+    clang::CompoundStmt *CS2 = dyn_cast<clang::CompoundStmt>(WS->getBody());
+    assert(CS2);
+    CS2->body_begin()[1] = B;
+    
+    CS->setRBracLoc(B->getLocEnd());
+    CS2->setRBracLoc(B->getLocEnd());
+  } else if (isa<MSDependentForEachStmt>(S)){
+    clang::MSDependentForEachStmt *S2 = dyn_cast<MSDependentForEachStmt>(S);
+    S2->setBody(B);
+  } else {
+    return StmtError();
+  }
+  return S;
+}
+
