1*89a1d03eSRichard // RUN: %check_clang_tidy %s modernize-loop-convert %t -- -- -I %S/Inputs/loop-convert 2*89a1d03eSRichard 3*89a1d03eSRichard #include "structures.h" 4*89a1d03eSRichard 5*89a1d03eSRichard namespace Array { 6*89a1d03eSRichard 7*89a1d03eSRichard const int N = 6; 8*89a1d03eSRichard const int NMinusOne = N - 1; 9*89a1d03eSRichard int Arr[N] = {1, 2, 3, 4, 5, 6}; 10*89a1d03eSRichard const int ConstArr[N] = {1, 2, 3, 4, 5, 6}; 11*89a1d03eSRichard int (*PArr)[N] = &Arr; 12*89a1d03eSRichard 13*89a1d03eSRichard void f() { 14*89a1d03eSRichard int Sum = 0; 15*89a1d03eSRichard 16*89a1d03eSRichard for (int I = 0; I < N; ++I) { 17*89a1d03eSRichard Sum += Arr[I]; 18*89a1d03eSRichard int K; 19*89a1d03eSRichard } 20*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead [modernize-loop-convert] 21*89a1d03eSRichard // CHECK-FIXES: for (int I : Arr) 22*89a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I; 23*89a1d03eSRichard // CHECK-FIXES-NEXT: int K; 24*89a1d03eSRichard 25*89a1d03eSRichard for (int I = 0; I < N; ++I) { 26*89a1d03eSRichard printf("Fibonacci number is %d\n", Arr[I]); 27*89a1d03eSRichard Sum += Arr[I] + 2; 28*89a1d03eSRichard } 29*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 30*89a1d03eSRichard // CHECK-FIXES: for (int I : Arr) 31*89a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); 32*89a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I + 2; 33*89a1d03eSRichard 34*89a1d03eSRichard for (int I = 0; I < N; ++I) { 35*89a1d03eSRichard int X = Arr[I]; 36*89a1d03eSRichard int Y = Arr[I] + 2; 37*89a1d03eSRichard } 38*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 39*89a1d03eSRichard // CHECK-FIXES: for (int I : Arr) 40*89a1d03eSRichard // CHECK-FIXES-NEXT: int X = I; 41*89a1d03eSRichard // CHECK-FIXES-NEXT: int Y = I + 2; 42*89a1d03eSRichard 43*89a1d03eSRichard for (int I = 0; I < N; ++I) { 44*89a1d03eSRichard int X = N; 45*89a1d03eSRichard X = Arr[I]; 46*89a1d03eSRichard } 47*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 48*89a1d03eSRichard // CHECK-FIXES: for (int I : Arr) 49*89a1d03eSRichard // CHECK-FIXES-NEXT: int X = N; 50*89a1d03eSRichard // CHECK-FIXES-NEXT: X = I; 51*89a1d03eSRichard 52*89a1d03eSRichard for (int I = 0; I < N; ++I) { 53*89a1d03eSRichard Arr[I] += 1; 54*89a1d03eSRichard } 55*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 56*89a1d03eSRichard // CHECK-FIXES: for (int & I : Arr) 57*89a1d03eSRichard // CHECK-FIXES-NEXT: I += 1; 58*89a1d03eSRichard 59*89a1d03eSRichard for (int I = 0; I < N; ++I) { 60*89a1d03eSRichard int X = Arr[I] + 2; 61*89a1d03eSRichard Arr[I]++; 62*89a1d03eSRichard } 63*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 64*89a1d03eSRichard // CHECK-FIXES: for (int & I : Arr) 65*89a1d03eSRichard // CHECK-FIXES-NEXT: int X = I + 2; 66*89a1d03eSRichard // CHECK-FIXES-NEXT: I++; 67*89a1d03eSRichard 68*89a1d03eSRichard for (int I = 0; I < N; ++I) { 69*89a1d03eSRichard Arr[I] = 4 + Arr[I]; 70*89a1d03eSRichard } 71*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 72*89a1d03eSRichard // CHECK-FIXES: for (int & I : Arr) 73*89a1d03eSRichard // CHECK-FIXES-NEXT: I = 4 + I; 74*89a1d03eSRichard 75*89a1d03eSRichard for (int I = 0; I < NMinusOne + 1; ++I) { 76*89a1d03eSRichard Sum += Arr[I]; 77*89a1d03eSRichard } 78*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 79*89a1d03eSRichard // CHECK-FIXES: for (int I : Arr) 80*89a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I; 81*89a1d03eSRichard 82*89a1d03eSRichard for (int I = 0; I < N; ++I) { 83*89a1d03eSRichard printf("Fibonacci number %d has address %p\n", Arr[I], &Arr[I]); 84*89a1d03eSRichard Sum += Arr[I] + 2; 85*89a1d03eSRichard } 86*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 87*89a1d03eSRichard // CHECK-FIXES: for (int & I : Arr) 88*89a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number %d has address %p\n", I, &I); 89*89a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I + 2; 90*89a1d03eSRichard 91*89a1d03eSRichard Val Teas[N]; 92*89a1d03eSRichard for (int I = 0; I < N; ++I) { 93*89a1d03eSRichard Teas[I].g(); 94*89a1d03eSRichard } 95*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 96*89a1d03eSRichard // CHECK-FIXES: for (auto & Tea : Teas) 97*89a1d03eSRichard // CHECK-FIXES-NEXT: Tea.g(); 98*89a1d03eSRichard 99*89a1d03eSRichard for (int I = 0; N > I; ++I) { 100*89a1d03eSRichard printf("Fibonacci number %d has address %p\n", Arr[I], &Arr[I]); 101*89a1d03eSRichard Sum += Arr[I] + 2; 102*89a1d03eSRichard } 103*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 104*89a1d03eSRichard // CHECK-FIXES: for (int & I : Arr) 105*89a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number %d has address %p\n", I, &I); 106*89a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I + 2; 107*89a1d03eSRichard 108*89a1d03eSRichard for (int I = 0; N != I; ++I) { 109*89a1d03eSRichard printf("Fibonacci number %d has address %p\n", Arr[I], &Arr[I]); 110*89a1d03eSRichard Sum += Arr[I] + 2; 111*89a1d03eSRichard } 112*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 113*89a1d03eSRichard // CHECK-FIXES: for (int & I : Arr) 114*89a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number %d has address %p\n", I, &I); 115*89a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I + 2; 116*89a1d03eSRichard 117*89a1d03eSRichard for (int I = 0; I != N; ++I) { 118*89a1d03eSRichard printf("Fibonacci number %d has address %p\n", Arr[I], &Arr[I]); 119*89a1d03eSRichard Sum += Arr[I] + 2; 120*89a1d03eSRichard } 121*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 122*89a1d03eSRichard // CHECK-FIXES: for (int & I : Arr) 123*89a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number %d has address %p\n", I, &I); 124*89a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I + 2; 125*89a1d03eSRichard } 126*89a1d03eSRichard 127*89a1d03eSRichard const int *constArray() { 128*89a1d03eSRichard for (int I = 0; I < N; ++I) { 129*89a1d03eSRichard printf("2 * %d = %d\n", ConstArr[I], ConstArr[I] + ConstArr[I]); 130*89a1d03eSRichard } 131*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 132*89a1d03eSRichard // CHECK-FIXES: for (int I : ConstArr) 133*89a1d03eSRichard // CHECK-FIXES-NEXT: printf("2 * %d = %d\n", I, I + I); 134*89a1d03eSRichard 135*89a1d03eSRichard const NonTriviallyCopyable NonCopy[N]{}; 136*89a1d03eSRichard for (int I = 0; I < N; ++I) { 137*89a1d03eSRichard printf("2 * %d = %d\n", NonCopy[I].X, NonCopy[I].X + NonCopy[I].X); 138*89a1d03eSRichard } 139*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 140*89a1d03eSRichard // CHECK-FIXES: for (const auto & I : NonCopy) 141*89a1d03eSRichard // CHECK-FIXES-NEXT: printf("2 * %d = %d\n", I.X, I.X + I.X); 142*89a1d03eSRichard 143*89a1d03eSRichard const TriviallyCopyableButBig Big[N]{}; 144*89a1d03eSRichard for (int I = 0; I < N; ++I) { 145*89a1d03eSRichard printf("2 * %d = %d\n", Big[I].X, Big[I].X + Big[I].X); 146*89a1d03eSRichard } 147*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 148*89a1d03eSRichard // CHECK-FIXES: for (const auto & I : Big) 149*89a1d03eSRichard // CHECK-FIXES-NEXT: printf("2 * %d = %d\n", I.X, I.X + I.X); 150*89a1d03eSRichard 151*89a1d03eSRichard bool Something = false; 152*89a1d03eSRichard for (int I = 0; I < N; ++I) { 153*89a1d03eSRichard if (Something) 154*89a1d03eSRichard return &ConstArr[I]; 155*89a1d03eSRichard } 156*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 157*89a1d03eSRichard // CHECK-FIXES: for (const int & I : ConstArr) 158*89a1d03eSRichard // CHECK-FIXES-NEXT: if (Something) 159*89a1d03eSRichard // CHECK-FIXES-NEXT: return &I; 160*89a1d03eSRichard } 161*89a1d03eSRichard 162*89a1d03eSRichard struct HasArr { 163*89a1d03eSRichard int Arr[N]; 164*89a1d03eSRichard Val ValArr[N]; 165*89a1d03eSRichard void implicitThis() { 166*89a1d03eSRichard for (int I = 0; I < N; ++I) { 167*89a1d03eSRichard printf("%d", Arr[I]); 168*89a1d03eSRichard } 169*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead 170*89a1d03eSRichard // CHECK-FIXES: for (int I : Arr) 171*89a1d03eSRichard // CHECK-FIXES-NEXT: printf("%d", I); 172*89a1d03eSRichard 173*89a1d03eSRichard for (int I = 0; I < N; ++I) { 174*89a1d03eSRichard printf("%d", ValArr[I].X); 175*89a1d03eSRichard } 176*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead 177*89a1d03eSRichard // CHECK-FIXES: for (auto & I : ValArr) 178*89a1d03eSRichard // CHECK-FIXES-NEXT: printf("%d", I.X); 179*89a1d03eSRichard } 180*89a1d03eSRichard 181*89a1d03eSRichard void explicitThis() { 182*89a1d03eSRichard for (int I = 0; I < N; ++I) { 183*89a1d03eSRichard printf("%d", this->Arr[I]); 184*89a1d03eSRichard } 185*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead 186*89a1d03eSRichard // CHECK-FIXES: for (int I : this->Arr) 187*89a1d03eSRichard // CHECK-FIXES-NEXT: printf("%d", I); 188*89a1d03eSRichard 189*89a1d03eSRichard for (int I = 0; I < N; ++I) { 190*89a1d03eSRichard printf("%d", this->ValArr[I].X); 191*89a1d03eSRichard } 192*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead 193*89a1d03eSRichard // CHECK-FIXES: for (auto & I : this->ValArr) 194*89a1d03eSRichard // CHECK-FIXES-NEXT: printf("%d", I.X); 195*89a1d03eSRichard } 196*89a1d03eSRichard }; 197*89a1d03eSRichard 198*89a1d03eSRichard struct HasIndirectArr { 199*89a1d03eSRichard HasArr HA; 200*89a1d03eSRichard void implicitThis() { 201*89a1d03eSRichard for (int I = 0; I < N; ++I) { 202*89a1d03eSRichard printf("%d", HA.Arr[I]); 203*89a1d03eSRichard } 204*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead 205*89a1d03eSRichard // CHECK-FIXES: for (int I : HA.Arr) 206*89a1d03eSRichard // CHECK-FIXES-NEXT: printf("%d", I); 207*89a1d03eSRichard 208*89a1d03eSRichard for (int I = 0; I < N; ++I) { 209*89a1d03eSRichard printf("%d", HA.ValArr[I].X); 210*89a1d03eSRichard } 211*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead 212*89a1d03eSRichard // CHECK-FIXES: for (auto & I : HA.ValArr) 213*89a1d03eSRichard // CHECK-FIXES-NEXT: printf("%d", I.X); 214*89a1d03eSRichard } 215*89a1d03eSRichard 216*89a1d03eSRichard void explicitThis() { 217*89a1d03eSRichard for (int I = 0; I < N; ++I) { 218*89a1d03eSRichard printf("%d", this->HA.Arr[I]); 219*89a1d03eSRichard } 220*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead 221*89a1d03eSRichard // CHECK-FIXES: for (int I : this->HA.Arr) 222*89a1d03eSRichard // CHECK-FIXES-NEXT: printf("%d", I); 223*89a1d03eSRichard 224*89a1d03eSRichard for (int I = 0; I < N; ++I) { 225*89a1d03eSRichard printf("%d", this->HA.ValArr[I].X); 226*89a1d03eSRichard } 227*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead 228*89a1d03eSRichard // CHECK-FIXES: for (auto & I : this->HA.ValArr) 229*89a1d03eSRichard // CHECK-FIXES-NEXT: printf("%d", I.X); 230*89a1d03eSRichard } 231*89a1d03eSRichard }; 232*89a1d03eSRichard 233*89a1d03eSRichard // Loops whose bounds are value-dependent should not be converted. 234*89a1d03eSRichard template <int N> 235*89a1d03eSRichard void dependentExprBound() { 236*89a1d03eSRichard for (int I = 0; I < N; ++I) 237*89a1d03eSRichard Arr[I] = 0; 238*89a1d03eSRichard } 239*89a1d03eSRichard template void dependentExprBound<20>(); 240*89a1d03eSRichard 241*89a1d03eSRichard void memberFunctionPointer() { 242*89a1d03eSRichard Val V; 243*89a1d03eSRichard void (Val::*mfpArr[N])(void) = {&Val::g}; 244*89a1d03eSRichard for (int I = 0; I < N; ++I) 245*89a1d03eSRichard (V.*mfpArr[I])(); 246*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 247*89a1d03eSRichard // CHECK-FIXES: for (auto & I : mfpArr) 248*89a1d03eSRichard // CHECK-FIXES-NEXT: (V.*I)(); 249*89a1d03eSRichard 250*89a1d03eSRichard struct Foo { 251*89a1d03eSRichard int (Val::*f)(); 252*89a1d03eSRichard } Foo[N]; 253*89a1d03eSRichard 254*89a1d03eSRichard for (int I = 0; I < N; ++I) 255*89a1d03eSRichard int R = (V.*(Foo[I].f))(); 256*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 257*89a1d03eSRichard // CHECK-FIXES: for (auto & I : Foo) 258*89a1d03eSRichard // CHECK-FIXES-NEXT: int R = (V.*(I.f))(); 259*89a1d03eSRichard 260*89a1d03eSRichard } 261*89a1d03eSRichard 262*89a1d03eSRichard } // namespace Array 263*89a1d03eSRichard 264*89a1d03eSRichard namespace Iterator { 265*89a1d03eSRichard 266*89a1d03eSRichard void f() { 267*89a1d03eSRichard /// begin()/end() - based for loops here: 268*89a1d03eSRichard T Tt; 269*89a1d03eSRichard for (T::iterator It = Tt.begin(), E = Tt.end(); It != E; ++It) { 270*89a1d03eSRichard printf("I found %d\n", *It); 271*89a1d03eSRichard } 272*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 273*89a1d03eSRichard // CHECK-FIXES: for (int & It : Tt) 274*89a1d03eSRichard // CHECK-FIXES-NEXT: printf("I found %d\n", It); 275*89a1d03eSRichard 276*89a1d03eSRichard // Do not crash because of Qq.begin() converting. Q::iterator converts with a 277*89a1d03eSRichard // conversion operator, which has no name, to Q::const_iterator. 278*89a1d03eSRichard Q Qq; 279*89a1d03eSRichard for (Q::const_iterator It = Qq.begin(), E = Qq.end(); It != E; ++It) { 280*89a1d03eSRichard printf("I found %d\n", *It); 281*89a1d03eSRichard } 282*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 283*89a1d03eSRichard // CHECK-FIXES: for (int & It : Qq) 284*89a1d03eSRichard // CHECK-FIXES-NEXT: printf("I found %d\n", It); 285*89a1d03eSRichard 286*89a1d03eSRichard T *Pt; 287*89a1d03eSRichard for (T::iterator It = Pt->begin(), E = Pt->end(); It != E; ++It) { 288*89a1d03eSRichard printf("I found %d\n", *It); 289*89a1d03eSRichard } 290*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 291*89a1d03eSRichard // CHECK-FIXES: for (int & It : *Pt) 292*89a1d03eSRichard // CHECK-FIXES-NEXT: printf("I found %d\n", It); 293*89a1d03eSRichard 294*89a1d03eSRichard S Ss; 295*89a1d03eSRichard for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) { 296*89a1d03eSRichard printf("s has value %d\n", (*It).X); 297*89a1d03eSRichard } 298*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 299*89a1d03eSRichard // CHECK-FIXES: for (auto & It : Ss) 300*89a1d03eSRichard // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X); 301*89a1d03eSRichard 302*89a1d03eSRichard S *Ps; 303*89a1d03eSRichard for (S::iterator It = Ps->begin(), E = Ps->end(); It != E; ++It) { 304*89a1d03eSRichard printf("s has value %d\n", (*It).X); 305*89a1d03eSRichard } 306*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 307*89a1d03eSRichard // CHECK-FIXES: for (auto & P : *Ps) 308*89a1d03eSRichard // CHECK-FIXES-NEXT: printf("s has value %d\n", P.X); 309*89a1d03eSRichard 310*89a1d03eSRichard for (S::const_iterator It = Ss.cbegin(), E = Ss.cend(); It != E; ++It) { 311*89a1d03eSRichard printf("s has value %d\n", (*It).X); 312*89a1d03eSRichard } 313*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 314*89a1d03eSRichard // CHECK-FIXES: for (auto It : Ss) 315*89a1d03eSRichard // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X); 316*89a1d03eSRichard 317*89a1d03eSRichard for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) { 318*89a1d03eSRichard printf("s has value %d\n", It->X); 319*89a1d03eSRichard } 320*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 321*89a1d03eSRichard // CHECK-FIXES: for (auto & It : Ss) 322*89a1d03eSRichard // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X); 323*89a1d03eSRichard 324*89a1d03eSRichard for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) { 325*89a1d03eSRichard It->X = 3; 326*89a1d03eSRichard } 327*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 328*89a1d03eSRichard // CHECK-FIXES: for (auto & It : Ss) 329*89a1d03eSRichard // CHECK-FIXES-NEXT: It.X = 3; 330*89a1d03eSRichard 331*89a1d03eSRichard for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) { 332*89a1d03eSRichard (*It).X = 3; 333*89a1d03eSRichard } 334*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 335*89a1d03eSRichard // CHECK-FIXES: for (auto & It : Ss) 336*89a1d03eSRichard // CHECK-FIXES-NEXT: It.X = 3; 337*89a1d03eSRichard 338*89a1d03eSRichard for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) { 339*89a1d03eSRichard It->nonConstFun(4, 5); 340*89a1d03eSRichard } 341*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 342*89a1d03eSRichard // CHECK-FIXES: for (auto & It : Ss) 343*89a1d03eSRichard // CHECK-FIXES-NEXT: It.nonConstFun(4, 5); 344*89a1d03eSRichard 345*89a1d03eSRichard U Uu; 346*89a1d03eSRichard for (U::iterator It = Uu.begin(), E = Uu.end(); It != E; ++It) { 347*89a1d03eSRichard printf("s has value %d\n", It->X); 348*89a1d03eSRichard } 349*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 350*89a1d03eSRichard // CHECK-FIXES: for (auto & It : Uu) 351*89a1d03eSRichard // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X); 352*89a1d03eSRichard 353*89a1d03eSRichard for (U::iterator It = Uu.begin(), E = Uu.end(); It != E; ++It) { 354*89a1d03eSRichard printf("s has value %d\n", (*It).X); 355*89a1d03eSRichard } 356*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 357*89a1d03eSRichard // CHECK-FIXES: for (auto & It : Uu) 358*89a1d03eSRichard // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X); 359*89a1d03eSRichard 360*89a1d03eSRichard for (U::iterator It = Uu.begin(), E = Uu.end(); It != E; ++It) { 361*89a1d03eSRichard Val* a = It.operator->(); 362*89a1d03eSRichard } 363*89a1d03eSRichard 364*89a1d03eSRichard U::iterator A; 365*89a1d03eSRichard for (U::iterator I = Uu.begin(), E = Uu.end(); I != E; ++I) 366*89a1d03eSRichard int K = A->X + I->X; 367*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 368*89a1d03eSRichard // CHECK-FIXES: for (auto & I : Uu) 369*89a1d03eSRichard // CHECK-FIXES-NEXT: int K = A->X + I.X; 370*89a1d03eSRichard 371*89a1d03eSRichard dependent<int> V; 372*89a1d03eSRichard for (dependent<int>::iterator It = V.begin(), E = V.end(); 373*89a1d03eSRichard It != E; ++It) { 374*89a1d03eSRichard printf("Fibonacci number is %d\n", *It); 375*89a1d03eSRichard } 376*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 377*89a1d03eSRichard // CHECK-FIXES: for (int & It : V) 378*89a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It); 379*89a1d03eSRichard 380*89a1d03eSRichard for (dependent<int>::iterator It(V.begin()), E = V.end(); 381*89a1d03eSRichard It != E; ++It) { 382*89a1d03eSRichard printf("Fibonacci number is %d\n", *It); 383*89a1d03eSRichard } 384*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 385*89a1d03eSRichard // CHECK-FIXES: for (int & It : V) 386*89a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It); 387*89a1d03eSRichard 388*89a1d03eSRichard doublyDependent<int, int> Intmap; 389*89a1d03eSRichard for (doublyDependent<int, int>::iterator It = Intmap.begin(), E = Intmap.end(); 390*89a1d03eSRichard It != E; ++It) { 391*89a1d03eSRichard printf("Intmap[%d] = %d", It->first, It->second); 392*89a1d03eSRichard } 393*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 394*89a1d03eSRichard // CHECK-FIXES: for (auto & It : Intmap) 395*89a1d03eSRichard // CHECK-FIXES: printf("Intmap[%d] = %d", It.first, It.second); 396*89a1d03eSRichard 397*89a1d03eSRichard // PtrSet's iterator dereferences by value so auto & can't be used. 398*89a1d03eSRichard { 399*89a1d03eSRichard PtrSet<int *> Val_int_ptrs; 400*89a1d03eSRichard for (PtrSet<int *>::iterator I = Val_int_ptrs.begin(), 401*89a1d03eSRichard E = Val_int_ptrs.end(); 402*89a1d03eSRichard I != E; ++I) { 403*89a1d03eSRichard (void) *I; 404*89a1d03eSRichard } 405*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-5]]:5: warning: use range-based for loop instead 406*89a1d03eSRichard // CHECK-FIXES: for (auto Val_int_ptr : Val_int_ptrs) 407*89a1d03eSRichard } 408*89a1d03eSRichard 409*89a1d03eSRichard // This container uses an iterator where the dereference type is a typedef of 410*89a1d03eSRichard // a reference type. Make sure non-const auto & is still used. A failure here 411*89a1d03eSRichard // means canonical types aren't being tested. 412*89a1d03eSRichard { 413*89a1d03eSRichard TypedefDerefContainer<int> Int_ptrs; 414*89a1d03eSRichard for (TypedefDerefContainer<int>::iterator I = Int_ptrs.begin(), 415*89a1d03eSRichard E = Int_ptrs.end(); 416*89a1d03eSRichard I != E; ++I) { 417*89a1d03eSRichard (void) *I; 418*89a1d03eSRichard } 419*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-5]]:5: warning: use range-based for loop instead 420*89a1d03eSRichard // CHECK-FIXES: for (int & Int_ptr : Int_ptrs) 421*89a1d03eSRichard } 422*89a1d03eSRichard 423*89a1d03eSRichard { 424*89a1d03eSRichard // Iterators returning an rvalue reference should disqualify the loop from 425*89a1d03eSRichard // transformation. 426*89a1d03eSRichard RValueDerefContainer<int> Container; 427*89a1d03eSRichard for (RValueDerefContainer<int>::iterator I = Container.begin(), 428*89a1d03eSRichard E = Container.end(); 429*89a1d03eSRichard I != E; ++I) { 430*89a1d03eSRichard (void) *I; 431*89a1d03eSRichard } 432*89a1d03eSRichard } 433*89a1d03eSRichard 434*89a1d03eSRichard dependent<Val *> Dpp; 435*89a1d03eSRichard for (dependent<Val *>::iterator I = Dpp.begin(), E = Dpp.end(); I != E; ++I) { 436*89a1d03eSRichard printf("%d\n", (**I).X); 437*89a1d03eSRichard } 438*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 439*89a1d03eSRichard // CHECK-FIXES: for (auto & I : Dpp) 440*89a1d03eSRichard // CHECK-FIXES-NEXT: printf("%d\n", (*I).X); 441*89a1d03eSRichard 442*89a1d03eSRichard for (dependent<Val *>::iterator I = Dpp.begin(), E = Dpp.end(); I != E; ++I) { 443*89a1d03eSRichard printf("%d\n", (*I)->X); 444*89a1d03eSRichard } 445*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 446*89a1d03eSRichard // CHECK-FIXES: for (auto & I : Dpp) 447*89a1d03eSRichard // CHECK-FIXES-NEXT: printf("%d\n", I->X); 448*89a1d03eSRichard } 449*89a1d03eSRichard 450*89a1d03eSRichard // Tests to verify the proper use of auto where the init variable type and the 451*89a1d03eSRichard // initializer type differ or are mostly the same except for const qualifiers. 452*89a1d03eSRichard void different_type() { 453*89a1d03eSRichard // Ss.begin() returns a type 'iterator' which is just a non-const pointer and 454*89a1d03eSRichard // differs from const_iterator only on the const qualification. 455*89a1d03eSRichard S Ss; 456*89a1d03eSRichard for (S::const_iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) { 457*89a1d03eSRichard printf("s has value %d\n", (*It).X); 458*89a1d03eSRichard } 459*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 460*89a1d03eSRichard // CHECK-FIXES: for (auto It : Ss) 461*89a1d03eSRichard // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X); 462*89a1d03eSRichard 463*89a1d03eSRichard S *Ps; 464*89a1d03eSRichard for (S::const_iterator It = Ps->begin(), E = Ps->end(); It != E; ++It) { 465*89a1d03eSRichard printf("s has value %d\n", (*It).X); 466*89a1d03eSRichard } 467*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 468*89a1d03eSRichard // CHECK-FIXES: for (auto P : *Ps) 469*89a1d03eSRichard // CHECK-FIXES-NEXT: printf("s has value %d\n", P.X); 470*89a1d03eSRichard 471*89a1d03eSRichard dependent<int> V; 472*89a1d03eSRichard for (dependent<int>::const_iterator It = V.begin(), E = V.end(); 473*89a1d03eSRichard It != E; ++It) { 474*89a1d03eSRichard printf("Fibonacci number is %d\n", *It); 475*89a1d03eSRichard } 476*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 477*89a1d03eSRichard // CHECK-FIXES: for (int It : V) 478*89a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It); 479*89a1d03eSRichard 480*89a1d03eSRichard for (dependent<int>::const_iterator It(V.begin()), E = V.end(); 481*89a1d03eSRichard It != E; ++It) { 482*89a1d03eSRichard printf("Fibonacci number is %d\n", *It); 483*89a1d03eSRichard } 484*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 485*89a1d03eSRichard // CHECK-FIXES: for (int It : V) 486*89a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It); 487*89a1d03eSRichard } 488*89a1d03eSRichard 489*89a1d03eSRichard // Tests to ensure that an implicit 'this' is picked up as the container. 490*89a1d03eSRichard // If member calls are made to 'this' within the loop, the transform becomes 491*89a1d03eSRichard // risky as these calls may affect state that affects the loop. 492*89a1d03eSRichard class C { 493*89a1d03eSRichard public: 494*89a1d03eSRichard typedef MutableVal *iterator; 495*89a1d03eSRichard typedef const MutableVal *const_iterator; 496*89a1d03eSRichard 497*89a1d03eSRichard iterator begin(); 498*89a1d03eSRichard iterator end(); 499*89a1d03eSRichard const_iterator begin() const; 500*89a1d03eSRichard const_iterator end() const; 501*89a1d03eSRichard 502*89a1d03eSRichard void doSomething(); 503*89a1d03eSRichard void doSomething() const; 504*89a1d03eSRichard 505*89a1d03eSRichard void doLoop() { 506*89a1d03eSRichard for (iterator I = begin(), E = end(); I != E; ++I) 507*89a1d03eSRichard (void) *I; 508*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead 509*89a1d03eSRichard // CHECK-FIXES: for (auto & I : *this) 510*89a1d03eSRichard 511*89a1d03eSRichard for (iterator I = C::begin(), E = C::end(); I != E; ++I) 512*89a1d03eSRichard (void) *I; 513*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead 514*89a1d03eSRichard // CHECK-FIXES: for (auto & I : *this) 515*89a1d03eSRichard 516*89a1d03eSRichard for (iterator I = begin(), E = end(); I != E; ++I) { 517*89a1d03eSRichard (void) *I; 518*89a1d03eSRichard doSomething(); 519*89a1d03eSRichard } 520*89a1d03eSRichard 521*89a1d03eSRichard for (iterator I = begin(); I != end(); ++I) 522*89a1d03eSRichard (void) *I; 523*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead 524*89a1d03eSRichard // CHECK-FIXES: for (auto & I : *this) 525*89a1d03eSRichard 526*89a1d03eSRichard for (iterator I = begin(); I != end(); ++I) { 527*89a1d03eSRichard (void) *I; 528*89a1d03eSRichard doSomething(); 529*89a1d03eSRichard } 530*89a1d03eSRichard } 531*89a1d03eSRichard 532*89a1d03eSRichard void doLoop() const { 533*89a1d03eSRichard for (const_iterator I = begin(), E = end(); I != E; ++I) 534*89a1d03eSRichard (void) *I; 535*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead 536*89a1d03eSRichard // CHECK-FIXES: for (auto I : *this) 537*89a1d03eSRichard 538*89a1d03eSRichard for (const_iterator I = C::begin(), E = C::end(); I != E; ++I) 539*89a1d03eSRichard (void) *I; 540*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead 541*89a1d03eSRichard // CHECK-FIXES: for (auto I : *this) 542*89a1d03eSRichard 543*89a1d03eSRichard for (const_iterator I = begin(), E = end(); I != E; ++I) { 544*89a1d03eSRichard (void) *I; 545*89a1d03eSRichard doSomething(); 546*89a1d03eSRichard } 547*89a1d03eSRichard } 548*89a1d03eSRichard }; 549*89a1d03eSRichard 550*89a1d03eSRichard class C2 { 551*89a1d03eSRichard public: 552*89a1d03eSRichard typedef MutableVal *iterator; 553*89a1d03eSRichard 554*89a1d03eSRichard iterator begin() const; 555*89a1d03eSRichard iterator end() const; 556*89a1d03eSRichard 557*89a1d03eSRichard void doLoop() { 558*89a1d03eSRichard // The implicit 'this' will have an Implicit cast to const C2* wrapped 559*89a1d03eSRichard // around it. Make sure the replacement still happens. 560*89a1d03eSRichard for (iterator I = begin(), E = end(); I != E; ++I) 561*89a1d03eSRichard (void) *I; 562*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead 563*89a1d03eSRichard // CHECK-FIXES: for (auto & I : *this) 564*89a1d03eSRichard } 565*89a1d03eSRichard }; 566*89a1d03eSRichard 567*89a1d03eSRichard } // namespace Iterator 568*89a1d03eSRichard 569*89a1d03eSRichard namespace PseudoArray { 570*89a1d03eSRichard 571*89a1d03eSRichard const int N = 6; 572*89a1d03eSRichard dependent<int> V; 573*89a1d03eSRichard dependent<int> *Pv; 574*89a1d03eSRichard const dependent<NonTriviallyCopyable> Constv; 575*89a1d03eSRichard const dependent<NonTriviallyCopyable> *Pconstv; 576*89a1d03eSRichard 577*89a1d03eSRichard transparent<dependent<int>> Cv; 578*89a1d03eSRichard 579*89a1d03eSRichard void f() { 580*89a1d03eSRichard int Sum = 0; 581*89a1d03eSRichard for (int I = 0, E = V.size(); I < E; ++I) { 582*89a1d03eSRichard printf("Fibonacci number is %d\n", V[I]); 583*89a1d03eSRichard Sum += V[I] + 2; 584*89a1d03eSRichard } 585*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 586*89a1d03eSRichard // CHECK-FIXES: for (int I : V) 587*89a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); 588*89a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I + 2; 589*89a1d03eSRichard 590*89a1d03eSRichard for (int I = 0, E = V.size(); I < E; ++I) { 591*89a1d03eSRichard printf("Fibonacci number is %d\n", V.at(I)); 592*89a1d03eSRichard Sum += V.at(I) + 2; 593*89a1d03eSRichard } 594*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 595*89a1d03eSRichard // CHECK-FIXES: for (int I : V) 596*89a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); 597*89a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I + 2; 598*89a1d03eSRichard 599*89a1d03eSRichard for (int I = 0, E = Pv->size(); I < E; ++I) { 600*89a1d03eSRichard printf("Fibonacci number is %d\n", Pv->at(I)); 601*89a1d03eSRichard Sum += Pv->at(I) + 2; 602*89a1d03eSRichard } 603*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 604*89a1d03eSRichard // CHECK-FIXES: for (int I : *Pv) 605*89a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); 606*89a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I + 2; 607*89a1d03eSRichard 608*89a1d03eSRichard // This test will fail if size() isn't called repeatedly, since it 609*89a1d03eSRichard // returns unsigned int, and 0 is deduced to be signed int. 610*89a1d03eSRichard // FIXME: Insert the necessary explicit conversion, or write out the types 611*89a1d03eSRichard // explicitly. 612*89a1d03eSRichard for (int I = 0; I < Pv->size(); ++I) { 613*89a1d03eSRichard printf("Fibonacci number is %d\n", (*Pv).at(I)); 614*89a1d03eSRichard Sum += (*Pv)[I] + 2; 615*89a1d03eSRichard } 616*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 617*89a1d03eSRichard // CHECK-FIXES: for (int I : *Pv) 618*89a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); 619*89a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I + 2; 620*89a1d03eSRichard 621*89a1d03eSRichard for (int I = 0; I < Cv->size(); ++I) { 622*89a1d03eSRichard printf("Fibonacci number is %d\n", Cv->at(I)); 623*89a1d03eSRichard Sum += Cv->at(I) + 2; 624*89a1d03eSRichard } 625*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 626*89a1d03eSRichard // CHECK-FIXES: for (int I : *Cv) 627*89a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); 628*89a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I + 2; 629*89a1d03eSRichard 630*89a1d03eSRichard for (int I = 0, E = V.size(); E > I; ++I) { 631*89a1d03eSRichard printf("Fibonacci number is %d\n", V[I]); 632*89a1d03eSRichard Sum += V[I] + 2; 633*89a1d03eSRichard } 634*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 635*89a1d03eSRichard // CHECK-FIXES: for (int I : V) 636*89a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); 637*89a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I + 2; 638*89a1d03eSRichard 639*89a1d03eSRichard for (int I = 0, E = V.size(); I != E; ++I) { 640*89a1d03eSRichard printf("Fibonacci number is %d\n", V[I]); 641*89a1d03eSRichard Sum += V[I] + 2; 642*89a1d03eSRichard } 643*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 644*89a1d03eSRichard // CHECK-FIXES: for (int I : V) 645*89a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); 646*89a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I + 2; 647*89a1d03eSRichard 648*89a1d03eSRichard for (int I = 0, E = V.size(); E != I; ++I) { 649*89a1d03eSRichard printf("Fibonacci number is %d\n", V[I]); 650*89a1d03eSRichard Sum += V[I] + 2; 651*89a1d03eSRichard } 652*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 653*89a1d03eSRichard // CHECK-FIXES: for (int I : V) 654*89a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); 655*89a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I + 2; 656*89a1d03eSRichard } 657*89a1d03eSRichard 658*89a1d03eSRichard // Ensure that 'const auto &' is used with containers of non-trivial types. 659*89a1d03eSRichard void constness() { 660*89a1d03eSRichard int Sum = 0; 661*89a1d03eSRichard for (int I = 0, E = Constv.size(); I < E; ++I) { 662*89a1d03eSRichard printf("Fibonacci number is %d\n", Constv[I].X); 663*89a1d03eSRichard Sum += Constv[I].X + 2; 664*89a1d03eSRichard } 665*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 666*89a1d03eSRichard // CHECK-FIXES: for (const auto & I : Constv) 667*89a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I.X); 668*89a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I.X + 2; 669*89a1d03eSRichard 670*89a1d03eSRichard for (int I = 0, E = Constv.size(); I < E; ++I) { 671*89a1d03eSRichard printf("Fibonacci number is %d\n", Constv.at(I).X); 672*89a1d03eSRichard Sum += Constv.at(I).X + 2; 673*89a1d03eSRichard } 674*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 675*89a1d03eSRichard // CHECK-FIXES: for (const auto & I : Constv) 676*89a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I.X); 677*89a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I.X + 2; 678*89a1d03eSRichard 679*89a1d03eSRichard for (int I = 0, E = Pconstv->size(); I < E; ++I) { 680*89a1d03eSRichard printf("Fibonacci number is %d\n", Pconstv->at(I).X); 681*89a1d03eSRichard Sum += Pconstv->at(I).X + 2; 682*89a1d03eSRichard } 683*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 684*89a1d03eSRichard // CHECK-FIXES: for (const auto & I : *Pconstv) 685*89a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I.X); 686*89a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I.X + 2; 687*89a1d03eSRichard 688*89a1d03eSRichard // This test will fail if size() isn't called repeatedly, since it 689*89a1d03eSRichard // returns unsigned int, and 0 is deduced to be signed int. 690*89a1d03eSRichard // FIXME: Insert the necessary explicit conversion, or write out the types 691*89a1d03eSRichard // explicitly. 692*89a1d03eSRichard for (int I = 0; I < Pconstv->size(); ++I) { 693*89a1d03eSRichard printf("Fibonacci number is %d\n", (*Pconstv).at(I).X); 694*89a1d03eSRichard Sum += (*Pconstv)[I].X + 2; 695*89a1d03eSRichard } 696*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 697*89a1d03eSRichard // CHECK-FIXES: for (const auto & I : *Pconstv) 698*89a1d03eSRichard // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I.X); 699*89a1d03eSRichard // CHECK-FIXES-NEXT: Sum += I.X + 2; 700*89a1d03eSRichard } 701*89a1d03eSRichard 702*89a1d03eSRichard void constRef(const dependent<int>& ConstVRef) { 703*89a1d03eSRichard int sum = 0; 704*89a1d03eSRichard // FIXME: This does not work with size_t (probably due to the implementation 705*89a1d03eSRichard // of dependent); make dependent work exactly like a std container type. 706*89a1d03eSRichard for (int I = 0; I < ConstVRef.size(); ++I) { 707*89a1d03eSRichard sum += ConstVRef[I]; 708*89a1d03eSRichard } 709*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 710*89a1d03eSRichard // CHECK-FIXES: for (int I : ConstVRef) 711*89a1d03eSRichard // CHECK-FIXES-NEXT: sum += I; 712*89a1d03eSRichard 713*89a1d03eSRichard for (auto I = ConstVRef.begin(), E = ConstVRef.end(); I != E; ++I) { 714*89a1d03eSRichard sum += *I; 715*89a1d03eSRichard } 716*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 717*89a1d03eSRichard // CHECK-FIXES: for (int I : ConstVRef) 718*89a1d03eSRichard // CHECK-FIXES-NEXT: sum += I; 719*89a1d03eSRichard } 720*89a1d03eSRichard 721*89a1d03eSRichard // Check for loops that don't mention containers. 722*89a1d03eSRichard void noContainer() { 723*89a1d03eSRichard for (auto I = 0; I < V.size(); ++I) { 724*89a1d03eSRichard } 725*89a1d03eSRichard 726*89a1d03eSRichard for (auto I = 0; I < V.size(); ++I) 727*89a1d03eSRichard ; 728*89a1d03eSRichard } 729*89a1d03eSRichard 730*89a1d03eSRichard struct NoBeginEnd { 731*89a1d03eSRichard unsigned size() const; 732*89a1d03eSRichard unsigned& operator[](int); 733*89a1d03eSRichard const unsigned& operator[](int) const; 734*89a1d03eSRichard }; 735*89a1d03eSRichard 736*89a1d03eSRichard struct NoConstBeginEnd { 737*89a1d03eSRichard NoConstBeginEnd(); 738*89a1d03eSRichard unsigned size() const; 739*89a1d03eSRichard unsigned* begin(); 740*89a1d03eSRichard unsigned* end(); 741*89a1d03eSRichard unsigned& operator[](int); 742*89a1d03eSRichard const unsigned& operator[](int) const; 743*89a1d03eSRichard }; 744*89a1d03eSRichard 745*89a1d03eSRichard struct ConstBeginEnd { 746*89a1d03eSRichard ConstBeginEnd(); 747*89a1d03eSRichard unsigned size() const; 748*89a1d03eSRichard unsigned* begin() const; 749*89a1d03eSRichard unsigned* end() const; 750*89a1d03eSRichard unsigned& operator[](int); 751*89a1d03eSRichard const unsigned& operator[](int) const; 752*89a1d03eSRichard }; 753*89a1d03eSRichard 754*89a1d03eSRichard // Shouldn't transform pseudo-array uses if the container doesn't provide 755*89a1d03eSRichard // begin() and end() of the right const-ness. 756*89a1d03eSRichard void NoBeginEndTest() { 757*89a1d03eSRichard NoBeginEnd NBE; 758*89a1d03eSRichard for (unsigned I = 0, E = NBE.size(); I < E; ++I) 759*89a1d03eSRichard printf("%d\n", NBE[I]); 760*89a1d03eSRichard 761*89a1d03eSRichard const NoConstBeginEnd Const_NCBE; 762*89a1d03eSRichard for (unsigned I = 0, E = Const_NCBE.size(); I < E; ++I) 763*89a1d03eSRichard printf("%d\n", Const_NCBE[I]); 764*89a1d03eSRichard 765*89a1d03eSRichard ConstBeginEnd CBE; 766*89a1d03eSRichard for (unsigned I = 0, E = CBE.size(); I < E; ++I) 767*89a1d03eSRichard printf("%d\n", CBE[I]); 768*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 769*89a1d03eSRichard // CHECK-FIXES: for (unsigned int I : CBE) 770*89a1d03eSRichard // CHECK-FIXES-NEXT: printf("%d\n", I); 771*89a1d03eSRichard 772*89a1d03eSRichard const ConstBeginEnd Const_CBE; 773*89a1d03eSRichard for (unsigned I = 0, E = Const_CBE.size(); I < E; ++I) 774*89a1d03eSRichard printf("%d\n", Const_CBE[I]); 775*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 776*89a1d03eSRichard // CHECK-FIXES: for (unsigned int I : Const_CBE) 777*89a1d03eSRichard // CHECK-FIXES-NEXT: printf("%d\n", I); 778*89a1d03eSRichard } 779*89a1d03eSRichard 780*89a1d03eSRichard struct DerefByValue { 781*89a1d03eSRichard DerefByValue(); 782*89a1d03eSRichard struct iter { unsigned operator*(); }; 783*89a1d03eSRichard unsigned size() const; 784*89a1d03eSRichard iter begin(); 785*89a1d03eSRichard iter end(); 786*89a1d03eSRichard unsigned operator[](int); 787*89a1d03eSRichard }; 788*89a1d03eSRichard 789*89a1d03eSRichard void derefByValueTest() { 790*89a1d03eSRichard DerefByValue DBV; 791*89a1d03eSRichard for (unsigned I = 0, E = DBV.size(); I < E; ++I) { 792*89a1d03eSRichard printf("%d\n", DBV[I]); 793*89a1d03eSRichard } 794*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead 795*89a1d03eSRichard // CHECK-FIXES: for (unsigned int I : DBV) 796*89a1d03eSRichard // CHECK-FIXES-NEXT: printf("%d\n", I); 797*89a1d03eSRichard 798*89a1d03eSRichard for (unsigned I = 0, E = DBV.size(); I < E; ++I) { 799*89a1d03eSRichard auto f = [DBV, I]() {}; 800*89a1d03eSRichard printf("%d\n", DBV[I]); 801*89a1d03eSRichard } 802*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead 803*89a1d03eSRichard // CHECK-FIXES: for (unsigned int I : DBV) 804*89a1d03eSRichard // CHECK-FIXES-NEXT: auto f = [DBV, &I]() {}; 805*89a1d03eSRichard // CHECK-FIXES-NEXT: printf("%d\n", I); 806*89a1d03eSRichard } 807*89a1d03eSRichard 808*89a1d03eSRichard void fundamentalTypesTest() { 809*89a1d03eSRichard const int N = 10; 810*89a1d03eSRichard bool Bools[N]; 811*89a1d03eSRichard for (int i = 0; i < N; ++i) 812*89a1d03eSRichard printf("%d", Bools[i]); 813*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 814*89a1d03eSRichard // CHECK-FIXES: for (bool Bool : Bools) 815*89a1d03eSRichard 816*89a1d03eSRichard int Ints[N]; 817*89a1d03eSRichard unsigned short int Shorts[N]; 818*89a1d03eSRichard for (int i = 0; i < N; ++i) 819*89a1d03eSRichard printf("%d", Shorts[i]); 820*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 821*89a1d03eSRichard // CHECK-FIXES: for (unsigned short Short : Shorts) 822*89a1d03eSRichard 823*89a1d03eSRichard signed long Longs[N]; 824*89a1d03eSRichard for (int i = 0; i < N; ++i) 825*89a1d03eSRichard printf("%d", Longs[i]); 826*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 827*89a1d03eSRichard // CHECK-FIXES: for (long Long : Longs) 828*89a1d03eSRichard 829*89a1d03eSRichard long long int LongLongs[N]; 830*89a1d03eSRichard for (int i = 0; i < N; ++i) 831*89a1d03eSRichard printf("%d", LongLongs[i]); 832*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 833*89a1d03eSRichard // CHECK-FIXES: for (long long LongLong : LongLongs) 834*89a1d03eSRichard 835*89a1d03eSRichard char Chars[N]; 836*89a1d03eSRichard for (int i = 0; i < N; ++i) 837*89a1d03eSRichard printf("%d", Chars[i]); 838*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 839*89a1d03eSRichard // CHECK-FIXES: for (char Char : Chars) 840*89a1d03eSRichard 841*89a1d03eSRichard wchar_t WChars[N]; 842*89a1d03eSRichard for (int i = 0; i < N; ++i) 843*89a1d03eSRichard printf("%d", WChars[i]); 844*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 845*89a1d03eSRichard // CHECK-FIXES: for (wchar_t WChar : WChars) 846*89a1d03eSRichard 847*89a1d03eSRichard float Floats[N]; 848*89a1d03eSRichard for (int i = 0; i < N; ++i) 849*89a1d03eSRichard printf("%d", Floats[i]); 850*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 851*89a1d03eSRichard // CHECK-FIXES: for (float Float : Floats) 852*89a1d03eSRichard 853*89a1d03eSRichard double Doubles[N]; 854*89a1d03eSRichard for (int i = 0; i < N; ++i) 855*89a1d03eSRichard printf("%d", Doubles[i]); 856*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead 857*89a1d03eSRichard // CHECK-FIXES: for (double Double : Doubles) 858*89a1d03eSRichard } 859*89a1d03eSRichard 860*89a1d03eSRichard } // namespace PseudoArray 861