diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h
index de042ca..8206656 100644
--- a/include/clang/AST/RecursiveASTVisitor.h
+++ b/include/clang/AST/RecursiveASTVisitor.h
@@ -1755,7 +1755,8 @@ template<typename Derived>
 bool RecursiveASTVisitor<Derived>::TraverseVarHelper(VarDecl *D) {
   TRY_TO(TraverseDeclaratorHelper(D));
   // Default params are taken care of when we traverse the ParmVarDecl.
-  if (!isa<ParmVarDecl>(D))
+  if (!isa<ParmVarDecl>(D) &&
+      (!D->isCXXForRangeDecl() || shouldVisitImplicitDeclarations()))
     TRY_TO(TraverseStmt(D->getInit()));
   return true;
 }
@@ -1873,7 +1874,14 @@ DEF_TRAVERSE_STMT(ObjCAtThrowStmt, { })
 DEF_TRAVERSE_STMT(ObjCAtTryStmt, { })
 DEF_TRAVERSE_STMT(ObjCForCollectionStmt, { })
 DEF_TRAVERSE_STMT(ObjCAutoreleasePoolStmt, { })
-DEF_TRAVERSE_STMT(CXXForRangeStmt, { })
+DEF_TRAVERSE_STMT(CXXForRangeStmt, {
+  if (!shouldVisitImplicitDeclarations()) {
+    TRY_TO(TraverseStmt(S->getLoopVarStmt()));
+    TRY_TO(TraverseStmt(S->getRangeInit()));
+    // Visit everything else only if shouldVisitImplicitDeclarations().
+    return true;
+  }
+})
 DEF_TRAVERSE_STMT(MSDependentExistsStmt, {
     TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
     TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
diff --git a/unittests/Tooling/RecursiveASTVisitorTest.cpp b/unittests/Tooling/RecursiveASTVisitorTest.cpp
index 52b3987..a1b2d48 100644
--- a/unittests/Tooling/RecursiveASTVisitorTest.cpp
+++ b/unittests/Tooling/RecursiveASTVisitorTest.cpp
@@ -142,6 +142,14 @@ public:
   }
 };
 
+class VarDeclVisitor : public ExpectedLocationVisitor<VarDeclVisitor> {
+public:
+ bool VisitVarDecl(VarDecl *Variable) {
+   Match(Variable->getNameAsString(), Variable->getLocStart());
+   return true;
+ }
+};
+
 class CXXMemberCallVisitor
   : public ExpectedLocationVisitor<CXXMemberCallVisitor> {
 public:
@@ -250,6 +258,22 @@ TEST(RecursiveASTVisitor, VisitsBaseClassTemplateArguments) {
     "void x(); template <void (*T)()> class X {};\nX<x> y;"));
 }
 
+TEST(RecursiveASTVisitor, VisitsCXXForRangeStmtRange) {
+  DeclRefExprVisitor Visitor;
+  Visitor.ExpectMatch("x", 2, 25);
+  EXPECT_TRUE(Visitor.runOver(
+    "int x[5];\n"
+    "void f() { for (int i : x) {} }"));
+}
+
+TEST(RecursiveASTVisitor, VisitsCXXForRangeStmtLoopVariable) {
+  VarDeclVisitor Visitor;
+  Visitor.ExpectMatch("i", 2, 17);
+  EXPECT_TRUE(Visitor.runOver(
+    "int x[5];\n"
+    "void f() { for (int i : x) {} }"));
+}
+
 TEST(RecursiveASTVisitor, VisitsCallExpr) {
   DeclRefExprVisitor Visitor;
   Visitor.ExpectMatch("x", 1, 22);
