Make LoopConvert work with containers that are used like arrays.
authorDaniel Jasper <djasper@google.com>
Mon, 12 Jan 2015 13:17:56 +0000 (13:17 +0000)
committerDaniel Jasper <djasper@google.com>
Mon, 12 Jan 2015 13:17:56 +0000 (13:17 +0000)
llvm-svn: 225629

clang-tools-extra/clang-modernize/LoopConvert/LoopActions.cpp
clang-tools-extra/test/clang-modernize/LoopConvert/naming-alias.cpp

index ed72694..11b3698 100644 (file)
@@ -450,9 +450,16 @@ static bool isAliasDecl(const Decl *TheDecl, const VarDecl *IndexVar) {
       const CXXOperatorCallExpr *OpCall = cast<CXXOperatorCallExpr>(Init);
       if (OpCall->getOperator() == OO_Star)
         return isDereferenceOfOpCall(OpCall, IndexVar);
+      if (OpCall->getOperator() == OO_Subscript) {
+        assert(OpCall->getNumArgs() == 2);
+        return true;
+      }
       break;
   }
 
+  case Stmt::CXXMemberCallExprClass:
+    return true;
+
   default:
     break;
   }
index 343dd0c..721f2b9 100644 (file)
@@ -7,6 +7,8 @@
 const int N = 10;
 
 Val Arr[N];
+dependent<Val> v;
+dependent<Val> *pv;
 Val &func(Val &);
 void sideEffect(int);
 
@@ -50,6 +52,25 @@ void aliasing() {
   // CHECK-NEXT: int y = t.x;
   // CHECK-NEXT: int z = elem.x + t.x;
 
+  // The same for pseudo-arrays like std::vector<T> (or here dependent<Val>)
+  // which provide a subscript operator[].
+  for (int i = 0; i < v.size(); ++i) {
+    Val &t = v[i]; { }
+    int y = t.x;
+  }
+  // CHECK: for (auto & t : v)
+  // CHECK-NEXT: { }
+  // CHECK-NEXT: int y = t.x;
+
+  // The same with a call to at()
+  for (int i = 0; i < pv->size(); ++i) {
+    Val &t = pv->at(i); { }
+    int y = t.x;
+  }
+  // CHECK: for (auto & t : *pv)
+  // CHECK-NEXT: { }
+  // CHECK-NEXT: int y = t.x;
+
   for (int i = 0; i < N; ++i) {
     Val &t = func(Arr[i]);
     int y = t.x;