Fix loop-convert for const references to containers.

Previously we would use a non-const loop variable in the range-based
loop for:
void f(const std::vector<int> &v) {
  for (size_t i = 0; i < v.size(); ++i) {
Now we use const auto&.

Note that we'll also want to use a copy at least for simple types.

llvm-svn: 248418
diff --git a/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp b/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
index 2c62372..054e5ce 100644
--- a/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
@@ -391,6 +391,12 @@
         return false;
       CType = CType->getPointeeType();
     }
+    // If VDec is a reference to a container, Dereference is false,
+    // but we still need to check the const-ness of the underlying container
+    // type.
+    if (const auto &RT = CType->getAs<ReferenceType>()) {
+      CType = RT->getPointeeType();
+    }
     return CType.isConstQualified();
   }
   return false;
diff --git a/clang-tools-extra/test/clang-tidy/modernize-loop-convert-basic.cpp b/clang-tools-extra/test/clang-tidy/modernize-loop-convert-basic.cpp
index dd16cb2..d3908b9 100644
--- a/clang-tools-extra/test/clang-tidy/modernize-loop-convert-basic.cpp
+++ b/clang-tools-extra/test/clang-tidy/modernize-loop-convert-basic.cpp
@@ -544,6 +544,18 @@
   // CHECK-FIXES-NEXT: sum += elem + 2;
 }
 
+void ConstRef(const dependent<int>& ConstVRef) {
+  int sum = 0;
+  // FIXME: This does not work with size_t (probably due to the implementation
+  // of dependent); make dependent work exactly like a std container type.
+  for (int i = 0; i < ConstVRef.size(); ++i) {
+    sum += ConstVRef[i];
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (const auto & elem : ConstVRef)
+  // CHECK-FIXES-NEXT: sum += elem;
+}
+
 // Check for loops that don't mention containers.
 void noContainer() {
   for (auto i = 0; i < v.size(); ++i) {