diff options
| author | Chandler Carruth <chandlerc@gmail.com> | 2013-09-04 17:35:07 +0000 |
|---|---|---|
| committer | Chandler Carruth <chandlerc@gmail.com> | 2013-09-04 17:35:07 +0000 |
| commit | d9063c46f59f4bec47bcbeddca8ca2f789348c03 (patch) | |
| tree | 76505542df7a05016dc71ffe44ed3ba264fb54be /clang-tools-extra/test/cpp11-migrate/LoopConvert | |
| parent | 6a23d212897d5402035cfaea82260f6dae1c8f2a (diff) | |
| download | bcm5719-llvm-d9063c46f59f4bec47bcbeddca8ca2f789348c03.tar.gz bcm5719-llvm-d9063c46f59f4bec47bcbeddca8ca2f789348c03.zip | |
Rename cpp11-migrate to clang-modernize.
There is no reason to expect this tool to be limited to C++11, it seems
very likely to be of on-going interest. It seems likely to be useful for
modernizing even as new libraries come out in TSes and other formats
than a complete standard. Fundamentally, we need something a bit more
general. After some discussion on the list, going with
'clang-modernize'.
I've tried to do a reasonably comprehensive job of fixing up the names,
but I may still have missed some. Feel free to poke me if you spot any
fallout here. Things I've tried reasonably hard to find and fix:
- cpp11-migrate -> clang-modernize
- Migrator -> Modernizer
- Clean up the introductory documentation that was C++11 specific.
I'll also point out that this tool continues to delight me. =] Also,
a huge thanks to those who have so carefully, thoroughly documented the
tool. The docs here are simply phenomenal. Every tool should be this
well documented. I hope I have updated the documentation reasonably
well, but I'm not very good at documentation, so review much
appreciated.
llvm-svn: 189960
Diffstat (limited to 'clang-tools-extra/test/cpp11-migrate/LoopConvert')
20 files changed, 0 insertions, 1824 deletions
diff --git a/clang-tools-extra/test/cpp11-migrate/LoopConvert/Inputs/macro_problem.h b/clang-tools-extra/test/cpp11-migrate/LoopConvert/Inputs/macro_problem.h deleted file mode 100644 index 42f28fde703..00000000000 --- a/clang-tools-extra/test/cpp11-migrate/LoopConvert/Inputs/macro_problem.h +++ /dev/null @@ -1,7 +0,0 @@ -#define myns nsblah - -namespace nsblah { -struct MyType { -}; - -} // namespace nsblah diff --git a/clang-tools-extra/test/cpp11-migrate/LoopConvert/Inputs/negative-header.h b/clang-tools-extra/test/cpp11-migrate/LoopConvert/Inputs/negative-header.h deleted file mode 100644 index 3962032da9d..00000000000 --- a/clang-tools-extra/test/cpp11-migrate/LoopConvert/Inputs/negative-header.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef NEGATIVE_HEADER_H -#define NEGATIVE_HEADER_H - -// Single FileCheck line to make sure that no loops are converted. -// CHECK-NOT: for ({{.*[^:]:[^:].*}}) -static void loopInHeader() { - const int N = 10; - int arr[N]; - int sum = 0; - for (int i = 0; i < N; ++i) - sum += arr[i]; -} - -#endif // NEGATIVE_HEADER_H diff --git a/clang-tools-extra/test/cpp11-migrate/LoopConvert/Inputs/structures.h b/clang-tools-extra/test/cpp11-migrate/LoopConvert/Inputs/structures.h deleted file mode 100644 index 9dd04f42b5a..00000000000 --- a/clang-tools-extra/test/cpp11-migrate/LoopConvert/Inputs/structures.h +++ /dev/null @@ -1,179 +0,0 @@ -#ifndef STRUCTURES_H -#define STRUCTURES_H - -extern "C" { -extern int printf(const char *restrict, ...); -} - -struct Val {int x; void g(); }; - -struct MutableVal { - void constFun(int) const; - void nonConstFun(int, int); - void constFun(MutableVal &) const; - void constParamFun(const MutableVal &) const; - void nonConstParamFun(const MutableVal &); - int x; -}; - -struct S { - typedef MutableVal *iterator; - typedef const MutableVal *const_iterator; - const_iterator begin() const; - const_iterator end() const; - iterator begin(); - iterator end(); -}; - -struct T { - struct iterator { - int& operator*(); - const int& operator*()const; - iterator& operator ++(); - bool operator!=(const iterator &other); - void insert(int); - int x; - }; - iterator begin(); - iterator end(); -}; - -struct U { - struct iterator { - Val& operator*(); - const Val& operator*()const; - iterator& operator ++(); - bool operator!=(const iterator &other); - Val *operator->(); - }; - iterator begin(); - iterator end(); - int x; -}; - -struct X { - S s; - T t; - U u; - S getS(); -}; - -template<typename ElemType> -class dependent{ - public: - struct iterator_base { - const ElemType& operator*()const; - iterator_base& operator ++(); - bool operator!=(const iterator_base &other) const; - const ElemType *operator->() const; - }; - - struct iterator : iterator_base { - ElemType& operator*(); - iterator& operator ++(); - ElemType *operator->(); - }; - - typedef iterator_base const_iterator; - const_iterator begin() const; - const_iterator end() const; - iterator begin(); - iterator end(); - unsigned size() const; - ElemType & operator[](unsigned); - const ElemType & operator[](unsigned) const; - ElemType & at(unsigned); - const ElemType & at(unsigned) const; - - // Intentionally evil. - dependent<ElemType> operator*(); - - void foo(); - void constFoo() const; -}; - -template<typename First, typename Second> -class doublyDependent{ - public: - struct Value { - First first; - Second second; - }; - - struct iterator_base { - const Value& operator*()const; - iterator_base& operator ++(); - bool operator!=(const iterator_base &other) const; - const Value *operator->() const; - }; - - struct iterator : iterator_base { - Value& operator*(); - Value& operator ++(); - Value *operator->(); - }; - - typedef iterator_base const_iterator; - const_iterator begin() const; - const_iterator end() const; - iterator begin(); - iterator end(); -}; - -template<typename Contained> -class transparent { - public: - Contained *at(); - Contained *operator->(); - Contained operator*(); -}; - -template<typename IteratorType> -struct Nested { - typedef IteratorType* iterator; - typedef const IteratorType* const_iterator; - IteratorType *operator->(); - IteratorType operator*(); - iterator begin(); - iterator end(); - const_iterator begin() const; - const_iterator end() const; -}; - -// Like llvm::SmallPtrSet, the iterator has a dereference operator that returns -// by value instead of by reference. -template <typename T> -struct PtrSet { - struct iterator { - bool operator!=(const iterator &other) const; - const T operator*(); - iterator &operator++(); - }; - iterator begin() const; - iterator end() const; -}; - -template <typename T> -struct TypedefDerefContainer { - struct iterator { - typedef T &deref_type; - bool operator!=(const iterator &other) const; - deref_type operator*(); - iterator &operator++(); - }; - iterator begin() const; - iterator end() const; -}; - -template <typename T> -struct RValueDerefContainer { - struct iterator { - typedef T &&deref_type; - bool operator!=(const iterator &other) const; - deref_type operator*(); - iterator &operator++(); - }; - iterator begin() const; - iterator end() const; -}; -#endif // STRUCTURES_H diff --git a/clang-tools-extra/test/cpp11-migrate/LoopConvert/array.cpp b/clang-tools-extra/test/cpp11-migrate/LoopConvert/array.cpp deleted file mode 100644 index 780fc3746bf..00000000000 --- a/clang-tools-extra/test/cpp11-migrate/LoopConvert/array.cpp +++ /dev/null @@ -1,155 +0,0 @@ -// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp -// RUN: cp %t.cpp %t.base -// RUN: cpp11-migrate -loop-convert %t.cpp -- -I %S/Inputs -// RUN: FileCheck -input-file=%t.cpp %s -// RUN: cp %t.base %t.cpp -// NORUN cpp11-migrate -count-only . %t.cpp -- -I %S/Inputs > %T/out -// NORUN FileCheck -check-prefix=COUNTONLY -input-file=%T/out %s -// RUN: diff %t.cpp %t.base - -#include "structures.h" - -const int N = 6; -const int NMinusOne = N - 1; -int arr[N] = {1, 2, 3, 4, 5, 6}; -int (*pArr)[N] = &arr; - -void f() { - int sum = 0; - // Update the number of correctly converted loops as this test changes: - // COUNTONLY: 15 converted - // COUNTONLY-NEXT: 0 potentially conflicting - // COUNTONLY-NEXT: 0 change(s) rejected - - for (int i = 0; i < N; ++i) { - sum += arr[i]; - int k; - } - // CHECK: for (auto & elem : arr) { - // CHECK-NEXT: sum += elem; - // CHECK-NEXT: int k; - // CHECK-NEXT: } - - for (int i = 0; i < N; ++i) { - printf("Fibonacci number is %d\n", arr[i]); - sum += arr[i] + 2; - } - // CHECK: for (auto & elem : arr) - // CHECK-NEXT: printf("Fibonacci number is %d\n", elem); - // CHECK-NEXT: sum += elem + 2; - - for (int i = 0; i < N; ++i) { - int x = arr[i]; - int y = arr[i] + 2; - } - // CHECK: for (auto & elem : arr) - // CHECK-NEXT: int x = elem; - // CHECK-NEXT: int y = elem + 2; - - for (int i = 0; i < N; ++i) { - int x = N; - x = arr[i]; - } - // CHECK: for (auto & elem : arr) - // CHECK-NEXT: int x = N; - // CHECK-NEXT: x = elem; - - for (int i = 0; i < N; ++i) { - arr[i] += 1; - } - // CHECK: for (auto & elem : arr) { - // CHECK-NEXT: elem += 1; - // CHECK-NEXT: } - - for (int i = 0; i < N; ++i) { - int x = arr[i] + 2; - arr[i] ++; - } - // CHECK: for (auto & elem : arr) - // CHECK-NEXT: int x = elem + 2; - // CHECK-NEXT: elem ++; - - for (int i = 0; i < N; ++i) { - arr[i] = 4 + arr[i]; - } - // CHECK: for (auto & elem : arr) - // CHECK-NEXT: elem = 4 + elem; - - for (int i = 0; i < NMinusOne + 1; ++i) { - sum += arr[i]; - } - // CHECK: for (auto & elem : arr) { - // CHECK-NEXT: sum += elem; - // CHECK-NEXT: } - - for (int i = 0; i < N; ++i) { - printf("Fibonacci number %d has address %p\n", arr[i], &arr[i]); - sum += arr[i] + 2; - } - // CHECK: for (auto & elem : arr) - // CHECK-NEXT: printf("Fibonacci number %d has address %p\n", elem, &elem); - // CHECK-NEXT: sum += elem + 2; - - Val teas[N]; - for (int i = 0; i < N; ++i) { - teas[i].g(); - } - // CHECK: for (auto & tea : teas) { - // CHECK-NEXT: tea.g(); - // CHECK-NEXT: } -} - -struct HasArr { - int Arr[N]; - Val ValArr[N]; - void implicitThis() { - for (int i = 0; i < N; ++i) { - printf("%d", Arr[i]); - } - // CHECK: for (auto & elem : Arr) { - // CHECK-NEXT: printf("%d", elem); - // CHECK-NEXT: } - - for (int i = 0; i < N; ++i) { - printf("%d", ValArr[i].x); - } - // CHECK: for (auto & elem : ValArr) { - // CHECK-NEXT: printf("%d", elem.x); - // CHECK-NEXT: } - } - - void explicitThis() { - for (int i = 0; i < N; ++i) { - printf("%d", this->Arr[i]); - } - // CHECK: for (auto & elem : this->Arr) { - // CHECK-NEXT: printf("%d", elem); - // CHECK-NEXT: } - - for (int i = 0; i < N; ++i) { - printf("%d", this->ValArr[i].x); - } - // CHECK: for (auto & elem : this->ValArr) { - // CHECK-NEXT: printf("%d", elem.x); - // CHECK-NEXT: } - } -}; - -// Loops whose bounds are value-dependent shold not be converted. -template<int N> -void dependentExprBound() { - for (int i = 0; i < N; ++i) - arr[i] = 0; - // CHECK: for (int i = 0; i < N; ++i) - // CHECK-NEXT: arr[i] = 0; -} -template void dependentExprBound<20>(); - -void memberFunctionPointer() { - Val v; - void (Val::*mfpArr[N])(void) = { &Val::g }; - for (int i = 0; i < N; ++i) - (v.*mfpArr[i])(); - // CHECK: for (auto & elem : mfpArr) - // CHECK-NEXT: (v.*elem)(); -} diff --git a/clang-tools-extra/test/cpp11-migrate/LoopConvert/confidence.cpp b/clang-tools-extra/test/cpp11-migrate/LoopConvert/confidence.cpp deleted file mode 100644 index 8c130f165b9..00000000000 --- a/clang-tools-extra/test/cpp11-migrate/LoopConvert/confidence.cpp +++ /dev/null @@ -1,35 +0,0 @@ -// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp -// RUN: cpp11-migrate -loop-convert %t.cpp -- -I %S/Inputs -// RUN: FileCheck -input-file=%t.cpp %s -// RUN: cpp11-migrate -loop-convert %t.cpp -risk=risky -- -I %S/Inputs -// RUN: FileCheck -check-prefix=RISKY -input-file=%t.cpp %s - -#include "structures.h" - -void f() { - const int N = 5; - const int M = 7; - int (*pArr)[N]; - int Arr[N][M]; - int sum = 0; - - for (int i = 0; i < M; ++i) { - sum += Arr[0][i]; - } - // CHECK: for (int i = 0; i < M; ++i) { - // CHECK-NEXT: sum += Arr[0][i]; - // CHECK-NEXT: } - // RISKY: for (auto & elem : Arr[0]) { - // RISKY-NEXT: sum += elem; - // RISKY-NEXT: } - - for (int i = 0; i < N; ++i) { - sum += (*pArr)[i]; - } - // RISKY: for (auto & elem : *pArr) { - // RISKY-NEXT: sum += elem; - // RISKY-NEXT: } - // CHECK: for (int i = 0; i < N; ++i) { - // CHECK-NEXT: sum += (*pArr)[i]; - // CHECK-NEXT: } -} diff --git a/clang-tools-extra/test/cpp11-migrate/LoopConvert/dependency.cpp b/clang-tools-extra/test/cpp11-migrate/LoopConvert/dependency.cpp deleted file mode 100644 index 15fffbab812..00000000000 --- a/clang-tools-extra/test/cpp11-migrate/LoopConvert/dependency.cpp +++ /dev/null @@ -1,26 +0,0 @@ -// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp -// RUN: cpp11-migrate -loop-convert %t.cpp -- && FileCheck -input-file=%t.cpp %s - -void f() { - const int N = 6; - const int M = 8; - int arr[N][M]; - - for (int i = 0; i < N; ++i) { - int a = 0; - int b = arr[i][a]; - } - // CHECK: for (auto & elem : arr) { - // CHECK-NEXT: int a = 0; - // CHECK-NEXT: int b = elem[a]; - // CHECK-NEXT: } - - for (int j = 0; j < M; ++j) { - int a = 0; - int b = arr[a][j]; - } - // CHECK: for (int j = 0; j < M; ++j) { - // CHECK-NEXT: int a = 0; - // CHECK-NEXT: int b = arr[a][j]; - // CHECK-NEXT: } -} diff --git a/clang-tools-extra/test/cpp11-migrate/LoopConvert/free_begin_end_fail.cpp b/clang-tools-extra/test/cpp11-migrate/LoopConvert/free_begin_end_fail.cpp deleted file mode 100644 index 27f7e8bf75e..00000000000 --- a/clang-tools-extra/test/cpp11-migrate/LoopConvert/free_begin_end_fail.cpp +++ /dev/null @@ -1,32 +0,0 @@ -// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp -// RUN: cpp11-migrate -loop-convert %t.cpp -- -I %S/Inputs -std=c++11 -// RUN: FileCheck -input-file=%t.cpp %s -// XFAIL: * - -struct MyArray { - unsigned size(); -}; - -template <typename T> -struct MyContainer { -}; - -int *begin(const MyArray &Arr); -int *end(const MyArray &Arr); - -template <typename T> -T *begin(const MyContainer<T> &C); -template <typename T> -T *end(const MyContainer<T> &C); - -// The Loop Convert Transform doesn't detect free functions begin()/end() and -// so fails to transform these cases which it should. -void f() { - MyArray Arr; - for (unsigned i = 0, e = Arr.size(); i < e; ++i) {} - // CHECK: for (auto & elem : Arr) {} - - MyContainer<int> C; - for (int *I = begin(C), *E = end(C); I != E; ++I) {} - // CHECK: for (auto & elem : C) {} -} diff --git a/clang-tools-extra/test/cpp11-migrate/LoopConvert/iterator.cpp b/clang-tools-extra/test/cpp11-migrate/LoopConvert/iterator.cpp deleted file mode 100644 index b8ba61b0a02..00000000000 --- a/clang-tools-extra/test/cpp11-migrate/LoopConvert/iterator.cpp +++ /dev/null @@ -1,244 +0,0 @@ -// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp -// RUN: cpp11-migrate -loop-convert %t.cpp -- -I %S/Inputs -std=c++11 -// RUN: FileCheck -input-file=%t.cpp %s -// RUN: cpp11-migrate -loop-convert %t.cpp -risk=risky -- -I %S/Inputs -// RUN: FileCheck -check-prefix=RISKY -input-file=%t.cpp %s - -#include "structures.h" - -void f() { - /// begin()/end() - based for loops here: - T t; - for (T::iterator it = t.begin(), e = t.end(); it != e; ++it) { - printf("I found %d\n", *it); - } - // CHECK: for (auto & elem : t) - // CHECK-NEXT: printf("I found %d\n", elem); - - T *pt; - for (T::iterator it = pt->begin(), e = pt->end(); it != e; ++it) { - printf("I found %d\n", *it); - } - // CHECK: for (auto & elem : *pt) - // CHECK-NEXT: printf("I found %d\n", elem); - - S s; - for (S::iterator it = s.begin(), e = s.end(); it != e; ++it) { - printf("s has value %d\n", (*it).x); - } - // CHECK: for (auto & elem : s) - // CHECK-NEXT: printf("s has value %d\n", (elem).x); - - S *ps; - for (S::iterator it = ps->begin(), e = ps->end(); it != e; ++it) { - printf("s has value %d\n", (*it).x); - } - // CHECK: for (auto & p : *ps) - // CHECK-NEXT: printf("s has value %d\n", (p).x); - - for (S::iterator it = s.begin(), e = s.end(); it != e; ++it) { - printf("s has value %d\n", it->x); - } - // CHECK: for (auto & elem : s) - // CHECK-NEXT: printf("s has value %d\n", elem.x); - - for (S::iterator it = s.begin(), e = s.end(); it != e; ++it) { - it->x = 3; - } - // CHECK: for (auto & elem : s) - // CHECK-NEXT: elem.x = 3; - - for (S::iterator it = s.begin(), e = s.end(); it != e; ++it) { - (*it).x = 3; - } - // CHECK: for (auto & elem : s) - // CHECK-NEXT: (elem).x = 3; - - for (S::iterator it = s.begin(), e = s.end(); it != e; ++it) { - it->nonConstFun(4, 5); - } - // CHECK: for (auto & elem : s) - // CHECK-NEXT: elem.nonConstFun(4, 5); - - U u; - for (U::iterator it = u.begin(), e = u.end(); it != e; ++it) { - printf("s has value %d\n", it->x); - } - // CHECK: for (auto & elem : u) - // CHECK-NEXT: printf("s has value %d\n", elem.x); - - for (U::iterator it = u.begin(), e = u.end(); it != e; ++it) { - printf("s has value %d\n", (*it).x); - } - // CHECK: for (auto & elem : u) - // CHECK-NEXT: printf("s has value %d\n", (elem).x); - - U::iterator A; - for (U::iterator i = u.begin(), e = u.end(); i != e; ++i) - int k = A->x + i->x; - // CHECK: for (auto & elem : u) - // CHECK-NEXT: int k = A->x + elem.x; - - dependent<int> v; - for (dependent<int>::iterator it = v.begin(), e = v.end(); - it != e; ++it) { - printf("Fibonacci number is %d\n", *it); - } - // CHECK: for (auto & elem : v) { - // CHECK-NEXT: printf("Fibonacci number is %d\n", elem); - - for (dependent<int>::iterator it(v.begin()), e = v.end(); - it != e; ++it) { - printf("Fibonacci number is %d\n", *it); - } - // CHECK: for (auto & elem : v) { - // CHECK-NEXT: printf("Fibonacci number is %d\n", elem); - - doublyDependent<int,int> intmap; - for (doublyDependent<int,int>::iterator it = intmap.begin(), e = intmap.end(); - it != e; ++it) { - printf("intmap[%d] = %d", it->first, it->second); - } - // CHECK: for (auto & elem : intmap) - // CHECK-NEXT: printf("intmap[%d] = %d", elem.first, elem.second); - - // PtrSet's iterator dereferences by value so auto & can't be used. - { - PtrSet<int*> int_ptrs; - for (PtrSet<int*>::iterator I = int_ptrs.begin(), - E = int_ptrs.end(); I != E; ++I) { - // CHECK: for (auto && int_ptr : int_ptrs) { - } - } - - // This container uses an iterator where the derefence type is a typedef of - // a reference type. Make sure non-const auto & is still used. A failure here - // means canonical types aren't being tested. - { - TypedefDerefContainer<int> int_ptrs; - for (TypedefDerefContainer<int>::iterator I = int_ptrs.begin(), - E = int_ptrs.end(); I != E; ++I) { - // CHECK: for (auto & int_ptr : int_ptrs) { - } - } - - { - // Iterators returning an rvalue reference should disqualify the loop from - // transformation. - RValueDerefContainer<int> container; - for (RValueDerefContainer<int>::iterator I = container.begin(), - E = container.end(); I != E; ++I) { - // CHECK: for (RValueDerefContainer<int>::iterator I = container.begin(), - // CHECK-NEXT: E = container.end(); I != E; ++I) { - } - } -} - -// Tests to verify the proper use of auto where the init variable type and the -// initializer type differ or are mostly the same except for const qualifiers. -void different_type() { - // s.begin() returns a type 'iterator' which is just a non-const pointer and - // differs from const_iterator only on the const qualification. - S s; - for (S::const_iterator it = s.begin(), e = s.end(); it != e; ++it) { - printf("s has value %d\n", (*it).x); - } - // CHECK: for (const auto & elem : s) - // CHECK-NEXT: printf("s has value %d\n", (elem).x); - - S *ps; - for (S::const_iterator it = ps->begin(), e = ps->end(); it != e; ++it) { - printf("s has value %d\n", (*it).x); - } - // CHECK: for (const auto & p : *ps) - // CHECK-NEXT: printf("s has value %d\n", (p).x); - - // v.begin() returns a user-defined type 'iterator' which, since it's - // different from const_iterator, disqualifies these loops from - // transformation. - dependent<int> v; - for (dependent<int>::const_iterator it = v.begin(), e = v.end(); - it != e; ++it) { - printf("Fibonacci number is %d\n", *it); - } - // CHECK: for (dependent<int>::const_iterator it = v.begin(), e = v.end(); - // CHECK-NEXT: it != e; ++it) { - // CHECK-NEXT: printf("Fibonacci number is %d\n", *it); - - for (dependent<int>::const_iterator it(v.begin()), e = v.end(); - it != e; ++it) { - printf("Fibonacci number is %d\n", *it); - } - // CHECK: for (dependent<int>::const_iterator it(v.begin()), e = v.end(); - // CHECK-NEXT: it != e; ++it) { - // CHECK-NEXT: printf("Fibonacci number is %d\n", *it); -} - -// Tests to ensure that an implicit 'this' is picked up as the container. -// If member calls are made to 'this' within the loop, the transform becomes -// risky as these calls may affect state that affects the loop. -class C { -public: - typedef MutableVal *iterator; - typedef const MutableVal *const_iterator; - - iterator begin(); - iterator end(); - const_iterator begin() const; - const_iterator end() const; - - void doSomething(); - void doSomething() const; - - void doLoop() { - for (iterator I = begin(), E = end(); I != E; ++I) { - // CHECK: for (auto & elem : *this) { - } - for (iterator I = C::begin(), E = C::end(); I != E; ++I) { - // CHECK: for (auto & elem : *this) { - } - for (iterator I = begin(), E = end(); I != E; ++I) { - // CHECK: for (iterator I = begin(), E = end(); I != E; ++I) { - // RISKY: for (auto & elem : *this) { - doSomething(); - } - for (iterator I = begin(); I != end(); ++I) { - // CHECK: for (auto & elem : *this) { - } - for (iterator I = begin(); I != end(); ++I) { - // CHECK: for (iterator I = begin(); I != end(); ++I) { - // RISKY: for (auto & elem : *this) { - doSomething(); - } - } - - void doLoop() const { - for (const_iterator I = begin(), E = end(); I != E; ++I) { - // CHECK: for (auto & elem : *this) { - } - for (const_iterator I = C::begin(), E = C::end(); I != E; ++I) { - // CHECK: for (auto & elem : *this) { - } - for (const_iterator I = begin(), E = end(); I != E; ++I) { - // CHECK: for (const_iterator I = begin(), E = end(); I != E; ++I) { - // RISKY: for (auto & elem : *this) { - doSomething(); - } - } -}; - -class C2 { -public: - typedef MutableVal *iterator; - - iterator begin() const; - iterator end() const; - - void doLoop() { - // The implicit 'this' will have an Implicit cast to const C2* wrapped - // around it. Make sure the replacement still happens. - for (iterator I = begin(), E = end(); I != E; ++I) { - // CHECK: for (auto & elem : *this) { - } - } -}; diff --git a/clang-tools-extra/test/cpp11-migrate/LoopConvert/macro_problem.cpp b/clang-tools-extra/test/cpp11-migrate/LoopConvert/macro_problem.cpp deleted file mode 100644 index 03dbddc3ea9..00000000000 --- a/clang-tools-extra/test/cpp11-migrate/LoopConvert/macro_problem.cpp +++ /dev/null @@ -1,22 +0,0 @@ -// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp -// RUN: cp %t.cpp %t.base -// RUN: cpp11-migrate -loop-convert %t.cpp -- -I %S/Inputs -// RUN: FileCheck -input-file=%t.cpp %s -// -// See PR15589 for why this test fails. -// XFAIL: * - -#include "macro_problem.h" -#include "structures.h" - -void side_effect(const myns::MyType &T); - -void f() { - TypedefDerefContainer<myns::MyType> container; - for (TypedefDerefContainer<myns::MyType>::iterator I = container.begin(), - E = container.end(); I != E; ++I) { - myns::MyType &alias = *I; - // CHECK: myns::MyType &ref = *I; - side_effect(ref); - } -} diff --git a/clang-tools-extra/test/cpp11-migrate/LoopConvert/naming-alias.cpp b/clang-tools-extra/test/cpp11-migrate/LoopConvert/naming-alias.cpp deleted file mode 100644 index 0ed3440ab77..00000000000 --- a/clang-tools-extra/test/cpp11-migrate/LoopConvert/naming-alias.cpp +++ /dev/null @@ -1,139 +0,0 @@ -// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp -// RUN: cpp11-migrate -loop-convert %t.cpp -- -I %S/Inputs -// RUN: FileCheck -input-file=%t.cpp %s - -#include "structures.h" - -const int N = 10; - -Val Arr[N]; -Val &func(Val &); -void sideEffect(int); - -void aliasing() { - // If the loop container is only used for a declaration of a temporary - // variable to hold each element, we can name the new variable for the - // converted range-based loop as the temporary variable's name. - - // In the following case, "t" is used as a temporary variable to hold each - // element, and thus we consider the name "t" aliased to the loop. - // The extra blank braces are left as a placeholder for after the variable - // declaration is deleted. - for (int i = 0; i < N; ++i) { - Val &t = Arr[i]; { } - int y = t.x; - } - // CHECK: for (auto & t : Arr) - // CHECK-NOT: Val &{{[a-z_]+}} = - // CHECK-NEXT: { } - // CHECK-NEXT: int y = t.x; - - // The container was not only used to initialize a temporary loop variable for - // the container's elements, so we do not alias the new loop variable. - for (int i = 0; i < N; ++i) { - Val &t = Arr[i]; - int y = t.x; - int z = Arr[i].x + t.x; - } - // CHECK: for (auto & elem : Arr) - // CHECK-NEXT: Val &t = elem; - // CHECK-NEXT: int y = t.x; - // CHECK-NEXT: int z = elem.x + t.x; - - for (int i = 0; i < N; ++i) { - Val t = Arr[i]; - int y = t.x; - int z = Arr[i].x + t.x; - } - // CHECK: for (auto & elem : Arr) - // CHECK-NEXT: Val t = elem; - // CHECK-NEXT: int y = t.x; - // CHECK-NEXT: int z = elem.x + t.x; - - for (int i = 0; i < N; ++i) { - Val &t = func(Arr[i]); - int y = t.x; - } - // CHECK: for (auto & elem : Arr) - // CHECK-NEXT: Val &t = func(elem); - // CHECK-NEXT: int y = t.x; - - int IntArr[N]; - for (unsigned i = 0; i < N; ++i) { - if (int alias = IntArr[i]) { - sideEffect(alias); - } - } - // CHECK: for (auto alias : IntArr) - // CHECK-NEXT: if (alias) { - - for (unsigned i = 0; i < N; ++i) { - while (int alias = IntArr[i]) { - sideEffect(alias); - } - } - // CHECK: for (auto alias : IntArr) - // CHECK-NEXT: while (alias) { - - for (unsigned i = 0; i < N; ++i) { - switch (int alias = IntArr[i]) { - default: - sideEffect(alias); - } - } - // CHECK: for (auto alias : IntArr) - // CHECK-NEXT: switch (alias) { - - for (unsigned i = 0; i < N; ++i) { - for (int alias = IntArr[i]; alias < N; ++alias) { - sideEffect(alias); - } - } - // CHECK: for (auto alias : IntArr) - // CHECK-NEXT: for (; alias < N; ++alias) { - - for (unsigned i = 0; i < N; ++i) { - for (unsigned j = 0; int alias = IntArr[i]; ++j) { - sideEffect(alias); - } - } - // CHECK: for (auto alias : IntArr) - // CHECK-NEXT: for (unsigned j = 0; alias; ++j) { -} - -void refs_and_vals() { - // The following tests check that the transform correctly preserves the - // reference or value qualifiers of the aliased variable. That is, if the - // variable was declared as a value, the loop variable will be declared as a - // value and vice versa for references. - - S s; - const S s_const = s; - - for (S::const_iterator it = s_const.begin(); it != s_const.end(); ++it) { - MutableVal alias = *it; { } - alias.x = 0; - } - // CHECK: for (auto alias : s_const) - // CHECK-NOT: MutableVal {{[a-z_]+}} = - // CHECK-NEXT: { } - // CHECK-NEXT: alias.x = 0; - - for (S::iterator it = s.begin(), e = s.end(); it != e; ++it) { - MutableVal alias = *it; { } - alias.x = 0; - } - // CHECK: for (auto alias : s) - // CHECK-NOT: MutableVal {{[a-z_]+}} = - // CHECK-NEXT: { } - // CHECK-NEXT: alias.x = 0; - - for (S::iterator it = s.begin(), e = s.end(); it != e; ++it) { - MutableVal &alias = *it; { } - alias.x = 0; - } - // CHECK: for (auto & alias : s) - // CHECK-NOT: MutableVal &{{[a-z_]+}} = - // CHECK-NEXT: { } - // CHECK-NEXT: alias.x = 0; -} diff --git a/clang-tools-extra/test/cpp11-migrate/LoopConvert/naming-conflict.cpp b/clang-tools-extra/test/cpp11-migrate/LoopConvert/naming-conflict.cpp deleted file mode 100644 index 2454d078e69..00000000000 --- a/clang-tools-extra/test/cpp11-migrate/LoopConvert/naming-conflict.cpp +++ /dev/null @@ -1,119 +0,0 @@ -// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp -// RUN: cpp11-migrate -loop-convert %t.cpp -- -I %S/Inputs -// RUN: FileCheck -input-file=%t.cpp %s - -#include "structures.h" - -#define MAX(a,b) (a > b) ? a : b -#define DEF 5 - -const int N = 10; -int nums[N]; -int sum = 0; - -namespace ns { - struct st { - int x; - }; -} - -void sameNames() { - int num = 0; - for (int i = 0; i < N; ++i) { - printf("Fibonacci number is %d\n", nums[i]); - sum += nums[i] + 2 + num; - (void) nums[i]; - } - // CHECK: for (auto & nums_i : nums) - // CHECK-NEXT: printf("Fibonacci number is %d\n", nums_i); - // CHECK-NEXT: sum += nums_i + 2 + num; - // CHECK-NOT: (void) num; -} - -void macroConflict() { - S MAXs; - for (S::iterator it = MAXs.begin(), e = MAXs.end(); it != e; ++it) { - printf("s has value %d\n", (*it).x); - printf("Max of 3 and 5: %d\n", MAX(3,5)); - } - // CHECK: for (auto & MAXs_it : MAXs) - // CHECK-NEXT: printf("s has value %d\n", (MAXs_it).x); - // CHECK-NEXT: printf("Max of 3 and 5: %d\n", MAX(3,5)); - - for (S::const_iterator it = MAXs.begin(), e = MAXs.end(); it != e; ++it) { - printf("s has value %d\n", (*it).x); - printf("Max of 3 and 5: %d\n", MAX(3,5)); - } - // CHECK: for (const auto & MAXs_it : MAXs) - // CHECK-NEXT: printf("s has value %d\n", (MAXs_it).x); - // CHECK-NEXT: printf("Max of 3 and 5: %d\n", MAX(3,5)); - - T DEFs; - for (T::iterator it = DEFs.begin(), e = DEFs.end(); it != e; ++it) { - if (*it == DEF) { - printf("I found %d\n", *it); - } - } - // CHECK: for (auto & DEFs_it : DEFs) - // CHECK-NEXT: if (DEFs_it == DEF) { - // CHECK-NEXT: printf("I found %d\n", DEFs_it); -} - -void keywordConflict() { - T ints; - for (T::iterator it = ints.begin(), e = ints.end(); it != e; ++it) { - *it = 5; - } - // CHECK: for (auto & ints_it : ints) - // CHECK-NEXT: ints_it = 5; - - U __FUNCTION__s; - for (U::iterator it = __FUNCTION__s.begin(), e = __FUNCTION__s.end(); - it != e; ++it) { - int __FUNCTION__s_it = (*it).x + 2; - } - // CHECK: for (auto & __FUNCTION__s_elem : __FUNCTION__s) - // CHECK-NEXT: int __FUNCTION__s_it = (__FUNCTION__s_elem).x + 2; -} - -void typeConflict() { - T Vals; - // Using the name "Val", although it is the name of an existing struct, is - // safe in this loop since it will only exist within this scope. - for (T::iterator it = Vals.begin(), e = Vals.end(); it != e; ++it) { - } - // CHECK: for (auto & Val : Vals) - - // We cannot use the name "Val" in this loop since there is a reference to - // it in the body of the loop. - for (T::iterator it = Vals.begin(), e = Vals.end(); it != e; ++it) { - *it = sizeof(Val); - } - // CHECK: for (auto & Vals_it : Vals) - // CHECK-NEXT: Vals_it = sizeof(Val); - - typedef struct Val TD; - U TDs; - // Naming the variable "TD" within this loop is safe because the typedef - // was never used within the loop. - for (U::iterator it = TDs.begin(), e = TDs.end(); it != e; ++it) { - } - // CHECK: for (auto & TD : TDs) - - // "TD" cannot be used in this loop since the typedef is being used. - for (U::iterator it = TDs.begin(), e = TDs.end(); it != e; ++it) { - TD V; - V.x = 5; - } - // CHECK: for (auto & TDs_it : TDs) - // CHECK-NEXT: TD V; - // CHECK-NEXT: V.x = 5; - - using ns::st; - T sts; - for (T::iterator it = sts.begin(), e = sts.end(); it != e; ++it) { - *it = sizeof(st); - } - // CHECK: for (auto & sts_it : sts) - // CHECK-NEXT: sts_it = sizeof(st); -} diff --git a/clang-tools-extra/test/cpp11-migrate/LoopConvert/negative-iterator.cpp b/clang-tools-extra/test/cpp11-migrate/LoopConvert/negative-iterator.cpp deleted file mode 100644 index 09c43476be2..00000000000 --- a/clang-tools-extra/test/cpp11-migrate/LoopConvert/negative-iterator.cpp +++ /dev/null @@ -1,160 +0,0 @@ -// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp -// RUN: cpp11-migrate -loop-convert %t.cpp -- -I %S/Inputs -// RUN: FileCheck -input-file=%t.cpp %s - -#include "structures.h" - -// Single FileCheck line to make sure that no loops are converted. -// CHECK-NOT: for ({{.*[^:]:[^:].*}}) - -S s; -T t; -U u; - -struct BadBeginEnd : T { - iterator notBegin(); - iterator notEnd(); -}; - -void notBeginOrEnd() { - BadBeginEnd Bad; - for (T::iterator i = Bad.notBegin(), e = Bad.end(); i != e; ++i) - int k = *i; - - for (T::iterator i = Bad.begin(), e = Bad.notEnd(); i != e; ++i) - int k = *i; -} - -void badLoopShapes() { - for (T::iterator i = t.begin(), e = t.end(), f = e; i != e; ++i) - int k = *i; - - for (T::iterator i = t.begin(), e = t.end(); i != e; ) - int k = *i; - - for (T::iterator i = t.begin(), e = t.end(); ; ++i) - int k = *i; - - T::iterator outsideI; - T::iterator outsideE; - - for (; outsideI != outsideE ; ++outsideI) - int k = *outsideI; -} - -void iteratorArrayMix() { - int lower; - const int N = 6; - for (T::iterator i = t.begin(), e = t.end(); lower < N; ++i) - int k = *i; - - for (T::iterator i = t.begin(), e = t.end(); lower < N; ++lower) - int k = *i; -} - -struct ExtraConstructor : T::iterator { - ExtraConstructor(T::iterator, int); - explicit ExtraConstructor(T::iterator); -}; - -void badConstructor() { - for (T::iterator i = ExtraConstructor(t.begin(), 0), e = t.end(); - i != e; ++i) - int k = *i; - for (T::iterator i = ExtraConstructor(t.begin()), e = t.end(); i != e; ++i) - int k = *i; -} - -void iteratorMemberUsed() { - for (T::iterator i = t.begin(), e = t.end(); i != e; ++i) - i.x = *i; - - for (T::iterator i = t.begin(), e = t.end(); i != e; ++i) - int k = i.x + *i; - - for (T::iterator i = t.begin(), e = t.end(); i != e; ++i) - int k = e.x + *i; -} - -void iteratorMethodCalled() { - for (T::iterator i = t.begin(), e = t.end(); i != e; ++i) - i.insert(3); - - for (T::iterator i = t.begin(), e = t.end(); i != e; ++i) - if (i != i) - int k = 3; -} - -void iteratorOperatorCalled() { - for (T::iterator i = t.begin(), e = t.end(); i != e; ++i) - int k = *(++i); - - for (S::iterator i = s.begin(), e = s.end(); i != e; ++i) - MutableVal k = *(++i); -} - -void differentContainers() { - T other; - for (T::iterator i = t.begin(), e = other.end(); i != e; ++i) - int k = *i; - - for (T::iterator i = other.begin(), e = t.end(); i != e; ++i) - int k = *i; - - S otherS; - for (S::iterator i = s.begin(), e = otherS.end(); i != e; ++i) - MutableVal k = *i; - - for (S::iterator i = otherS.begin(), e = s.end(); i != e; ++i) - MutableVal k = *i; -} - -void wrongIterators() { - T::iterator other; - for (T::iterator i = t.begin(), e = t.end(); i != other; ++i) - int k = *i; -} - -struct EvilArrow : U { - // Please, no one ever write code like this. - U* operator->(); -}; - -void differentMemberAccessTypes() { - EvilArrow A; - for (EvilArrow::iterator i = A.begin(), e = A->end(); i != e; ++i) - Val k = *i; - for (EvilArrow::iterator i = A->begin(), e = A.end(); i != e; ++i) - Val k = *i; -} - -void f(const T::iterator &it, int); -void f(const T &it, int); -void g(T &it, int); - -void iteratorPassedToFunction() { - for (T::iterator i = t.begin(), e = t.end(); i != e; ++i) - f(i, *i); -} - -// FIXME: Disallow this except for containers passed by value and/or const -// reference. Or maybe this is correct enough for any container? -void containerPassedToFunction() { -// for (T::iterator i = t.begin(), e = t.end(); i != e; ++i) -// f(t, *i); -// for (T::iterator i = t.begin(), e = t.end(); i != e; ++i) -// g(t, *i); -} - -// FIXME: These tests can be removed if this tool ever does enough analysis to -// decide that this is a safe transformation. -// Until then, we don't want it applied. -void iteratorDefinedOutside() { - T::iterator theEnd = t.end(); - for (T::iterator i = t.begin(); i != theEnd; ++i) - int k = *i; - - T::iterator theBegin = t.begin(); - for (T::iterator e = t.end(); theBegin != e; ++theBegin) - int k = *theBegin; -} diff --git a/clang-tools-extra/test/cpp11-migrate/LoopConvert/negative-multi-end-call.cpp b/clang-tools-extra/test/cpp11-migrate/LoopConvert/negative-multi-end-call.cpp deleted file mode 100644 index 6e50ee72e35..00000000000 --- a/clang-tools-extra/test/cpp11-migrate/LoopConvert/negative-multi-end-call.cpp +++ /dev/null @@ -1,64 +0,0 @@ -// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp -// RUN: cpp11-migrate -loop-convert -risk=safe %t.cpp -- -I %S/Inputs -// RUN: FileCheck -input-file=%t.cpp %s - -#include "structures.h" - -// Single FileCheck line to make sure that no loops are converted. -// CHECK-NOT: for ({{.*[^:]:[^:].*}}) - -S s; -T t; -U u; - -void multipleEnd() { - for (S::iterator i = s.begin(); i != s.end(); ++i) - MutableVal k = *i; - - for (T::iterator i = t.begin(); i != t.end(); ++i) - int k = *i; - - for (U::iterator i = u.begin(); i != u.end(); ++i) - Val k = *i; -} - -void f(X); -void f(S); -void f(T); - -void complexContainer() { - X x; - for (S::iterator i = x.s.begin(), e = x.s.end(); i != e; ++i) { - f(x); - MutableVal k = *i; - } - - for (T::iterator i = x.t.begin(), e = x.t.end(); i != e; ++i) { - f(x); - int k = *i; - } - - for (S::iterator i = x.s.begin(), e = x.s.end(); i != e; ++i) { - f(x.s); - MutableVal k = *i; - } - - for (T::iterator i = x.t.begin(), e = x.t.end(); i != e; ++i) { - f(x.t); - int k = *i; - } - - for (S::iterator i = x.getS().begin(), e = x.getS().end(); i != e; ++i) { - f(x.getS()); - MutableVal k = *i; - } - - X exes[5]; - int index = 0; - - for (S::iterator i = exes[index].getS().begin(), - e = exes[index].getS().end(); i != e; ++i) { - index++; - MutableVal k = *i; - } -} diff --git a/clang-tools-extra/test/cpp11-migrate/LoopConvert/negative-pseudoarray-extra.cpp b/clang-tools-extra/test/cpp11-migrate/LoopConvert/negative-pseudoarray-extra.cpp deleted file mode 100644 index 3ccdb12c620..00000000000 --- a/clang-tools-extra/test/cpp11-migrate/LoopConvert/negative-pseudoarray-extra.cpp +++ /dev/null @@ -1,29 +0,0 @@ -// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp -// RUN: cpp11-migrate -loop-convert %t.cpp -- -I %S/Inputs -// RUN: FileCheck -input-file=%t.cpp %s - -#include "structures.h" - -// Single FileCheck line to make sure that no loops are converted. -// CHECK-NOT: for ({{.*[^:]:[^:].*}}) - -const int N = 6; -dependent<int> v; -dependent<int> *pv; - -int sum = 0; - -// Checks to see that non-const member functions are not called on the container -// object. -// These could be conceivably allowed with a lower required confidence level. -void memberFunctionCalled() { - for (int i = 0; i < v.size(); ++i) { - sum += v[i]; - v.foo(); - } - - for (int i = 0; i < v.size(); ++i) { - sum += v[i]; - dependent<int>::iterator it = v.begin(); - } -} diff --git a/clang-tools-extra/test/cpp11-migrate/LoopConvert/negative-pseudoarray.cpp b/clang-tools-extra/test/cpp11-migrate/LoopConvert/negative-pseudoarray.cpp deleted file mode 100644 index cbc67be24af..00000000000 --- a/clang-tools-extra/test/cpp11-migrate/LoopConvert/negative-pseudoarray.cpp +++ /dev/null @@ -1,129 +0,0 @@ -// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp -// RUN: cpp11-migrate -loop-convert %t.cpp -- -I %S/Inputs -// RUN: FileCheck -input-file=%t.cpp %s - -#include "structures.h" - -// Single FileCheck line to make sure that no loops are converted. -// CHECK-NOT: for ({{.*[^:]:[^:].*}}) - -const int N = 6; -dependent<int> v; -dependent<int> *pv; - -transparent<dependent<int> > cv; -int sum = 0; - -// Checks for the index start and end: -void indexStartAndEnd() { - for (int i = 0; i < v.size() + 1; ++i) - sum += v[i]; - - for (int i = 0; i < v.size() - 1; ++i) - sum += v[i]; - - for (int i = 1; i < v.size(); ++i) - sum += v[i]; - - for (int i = 1; i < v.size(); ++i) - sum += v[i]; - - for (int i = 0; ; ++i) - sum += (*pv)[i]; -} - -// Checks for invalid increment steps: -void increment() { - for (int i = 0; i < v.size(); --i) - sum += v[i]; - - for (int i = 0; i < v.size(); i) - sum += v[i]; - - for (int i = 0; i < v.size();) - sum += v[i]; - - for (int i = 0; i < v.size(); i += 2) - sum ++; -} - -// Checks to make sure that the index isn't used outside of the container: -void indexUse() { - for (int i = 0; i < v.size(); ++i) - v[i] += 1 + i; -} - -// Checks for incorrect loop variables. -void mixedVariables() { - int badIndex; - for (int i = 0; badIndex < v.size(); ++i) - sum += v[i]; - - for (int i = 0; i < v.size(); ++badIndex) - sum += v[i]; - - for (int i = 0; badIndex < v.size(); ++badIndex) - sum += v[i]; - - for (int i = 0; badIndex < v.size(); ++badIndex) - sum += v[badIndex]; -} - -// Checks for an array indexed in addition to the container. -void multipleArrays() { - int badArr[N]; - - for (int i = 0; i < v.size(); ++i) - sum += v[i] + badArr[i]; - - for (int i = 0; i < v.size(); ++i) - sum += badArr[i]; - - for (int i = 0; i < v.size(); ++i) { - int k = badArr[i]; - sum += k + 2; - } - - for (int i = 0; i < v.size(); ++i) { - int k = badArr[i]; - sum += v[i] + k; - } -} - -// Checks for multiple containers being indexed container. -void multipleContainers() { - dependent<int> badArr; - - for (int i = 0; i < v.size(); ++i) - sum += v[i] + badArr[i]; - - for (int i = 0; i < v.size(); ++i) - sum += badArr[i]; - - for (int i = 0; i < v.size(); ++i) { - int k = badArr[i]; - sum += k + 2; - } - - for (int i = 0; i < v.size(); ++i) { - int k = badArr[i]; - sum += v[i] + k; - } -} - -// Check to make sure that dereferenced pointers-to-containers behave nicely -void derefContainer() { - // Note the dependent<T>::operator*() returns another dependent<T>. - // This test makes sure that we don't allow an arbitrary number of *'s. - for (int i = 0; i < pv->size(); ++i) - sum += (**pv).at(i); - - for (int i = 0; i < pv->size(); ++i) - sum += (**pv)[i]; -} - -void wrongEnd() { - int bad; - for (int i = 0, e = v.size(); i < bad; ++i) - sum += v[i]; -} diff --git a/clang-tools-extra/test/cpp11-migrate/LoopConvert/negative.cpp b/clang-tools-extra/test/cpp11-migrate/LoopConvert/negative.cpp deleted file mode 100644 index 0075f5eab69..00000000000 --- a/clang-tools-extra/test/cpp11-migrate/LoopConvert/negative.cpp +++ /dev/null @@ -1,123 +0,0 @@ -// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp -// RUN: grep -Ev "// *[A-Z-]+:" %S/Inputs/negative-header.h > \ -// RUN: %T/negative-header.h -// RUN: cpp11-migrate -loop-convert %t.cpp -- -I %S/Inputs/ -// RUN: FileCheck -input-file=%t.cpp %s -// RUN: FileCheck -input-file=%T/negative-header.h %S/Inputs/negative-header.h - -#include "negative-header.h" -#include "structures.h" - -// Single FileCheck line to make sure that no loops are converted. -// CHECK-NOT: for ({{.*[^:]:[^:].*}}) - -const int N = 6; -int arr[N] = {1, 2, 3, 4, 5, 6}; -int (*pArr)[N] = &arr; -int sum = 0; - -// Checks for the index start and end: -void indexStartAndEnd() { - for (int i = 0; i < N + 1; ++i) - sum += arr[i]; - - for (int i = 0; i < N - 1; ++i) - sum += arr[i]; - - for (int i = 1; i < N; ++i) - sum += arr[i]; - - for (int i = 1; i < N; ++i) - sum += arr[i]; - - for (int i = 0; ; ++i) - sum += (*pArr)[i]; -} - -// Checks for invalid increment steps: -void increment() { - for (int i = 0; i < N; --i) - sum += arr[i]; - - for (int i = 0; i < N; i) - sum += arr[i]; - - for (int i = 0; i < N;) - sum += arr[i]; - - for (int i = 0; i < N; i += 2) - sum ++; -} - -// Checks to make sure that the index isn't used outside of the array: -void indexUse() { - for (int i = 0; i < N; ++i) - arr[i] += 1 + i; -} - -// Check for loops that don't mention arrays -void noArray() { - for (int i = 0; i < N; ++i) - sum += i; - - for (int i = 0; i < N; ++i) { } - - for (int i = 0; i < N; ++i) ; -} - -// Checks for incorrect loop variables. -void mixedVariables() { - int badIndex; - for (int i = 0; badIndex < N; ++i) - sum += arr[i]; - - for (int i = 0; i < N; ++badIndex) - sum += arr[i]; - - for (int i = 0; badIndex < N; ++badIndex) - sum += arr[i]; - - for (int i = 0; badIndex < N; ++badIndex) - sum += arr[badIndex]; -} - -// Checks for multiple arrays indexed. -void multipleArrays() { - int badArr[N]; - - for (int i = 0; i < N; ++i) - sum += arr[i] + badArr[i]; - - for (int i = 0; i < N; ++i) { - int k = badArr[i]; - sum += arr[i] + k; - } -} - -struct HasArr { - int Arr[N]; - Val ValArr[N]; -}; - -struct HasIndirectArr { - HasArr HA; - void implicitThis() { - for (int i = 0; i < N; ++i) { - printf("%d", HA.Arr[i]); - } - - for (int i = 0; i < N; ++i) { - printf("%d", HA.ValArr[i].x); - } - } - - void explicitThis() { - for (int i = 0; i < N; ++i) { - printf("%d", this->HA.Arr[i]); - } - - for (int i = 0; i < N; ++i) { - printf("%d", this->HA.ValArr[i].x); - } - } -}; diff --git a/clang-tools-extra/test/cpp11-migrate/LoopConvert/nesting.cpp b/clang-tools-extra/test/cpp11-migrate/LoopConvert/nesting.cpp deleted file mode 100644 index 33ab5d401b3..00000000000 --- a/clang-tools-extra/test/cpp11-migrate/LoopConvert/nesting.cpp +++ /dev/null @@ -1,69 +0,0 @@ -// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp -// RUN: cpp11-migrate -loop-convert %t.cpp -- -I %S/Inputs -// RUN: FileCheck -input-file=%t.cpp %s - -#include "structures.h" - -void f() { - const int N = 10; - const int M = 15; - Val Arr[N]; - for (int i = 0; i < N; ++i) { - for (int j = 0; j < N; ++j) { - int k = Arr[i].x + Arr[j].x; - // The repeat is there to allow FileCheck to make sure the two variable - // names aren't the same. - int l = Arr[i].x + Arr[j].x; - } - } - // CHECK: for (auto & elem : Arr) - // CHECK-NEXT: for (auto & Arr_j : Arr) - // CHECK-NEXT: int k = elem.x + Arr_j.x; - // CHECK-NOT: int l = elem.x + elem.x; - - Val Nest[N][M]; - for (int i = 0; i < N; ++i) { - for (int j = 0; j < M; ++j) { - printf("Got item %d", Nest[i][j].x); - } - } - // The inner loop is also convertible, but doesn't need to be converted - // immediately. Update this test when that changes! - // CHECK: for (auto & elem : Nest) - // CHECK-NEXT: for (int j = 0; j < M; ++j) - // CHECK-NEXT: printf("Got item %d", elem[j].x); - - // Note that the order of M and N are switched for this test. - for (int j = 0; j < M; ++j) { - for (int i = 0; i < N; ++i) { - printf("Got item %d", Nest[i][j].x); - } - } - // CHECK-NOT: for (auto & {{[a-zA-Z_]+}} : Nest[i]) - // CHECK: for (int j = 0; j < M; ++j) - // CHECK-NEXT: for (auto & elem : Nest) - // CHECK-NEXT: printf("Got item %d", elem[j].x); - Nested<T> NestT; - for (Nested<T>::iterator I = NestT.begin(), E = NestT.end(); I != E; ++I) { - for (T::iterator TI = (*I).begin(), TE = (*I).end(); TI != TE; ++TI) { - printf("%d", *TI); - } - } - // The inner loop is also convertible, but doesn't need to be converted - // immediately. Update this test when that changes! - // CHECK: for (auto & elem : NestT) { - // CHECK-NEXT: for (T::iterator TI = (elem).begin(), TE = (elem).end(); TI != TE; ++TI) { - // CHECK-NEXT: printf("%d", *TI); - - Nested<S> NestS; - for (Nested<S>::const_iterator I = NestS.begin(), E = NestS.end(); I != E; ++I) { - for (S::const_iterator SI = (*I).begin(), SE = (*I).end(); SI != SE; ++SI) { - printf("%d", *SI); - } - } - // The inner loop is also convertible, but doesn't need to be converted - // immediately. Update this test when that changes! - // CHECK: for (const auto & elem : NestS) { - // CHECK-NEXT: for (S::const_iterator SI = (elem).begin(), SE = (elem).end(); SI != SE; ++SI) { - // CHECK-NEXT: printf("%d", *SI); -} diff --git a/clang-tools-extra/test/cpp11-migrate/LoopConvert/nocompile.cpp b/clang-tools-extra/test/cpp11-migrate/LoopConvert/nocompile.cpp deleted file mode 100644 index ea102877557..00000000000 --- a/clang-tools-extra/test/cpp11-migrate/LoopConvert/nocompile.cpp +++ /dev/null @@ -1,21 +0,0 @@ -// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp -// RUN: not cpp11-migrate -loop-convert %t.cpp -- -I %S/Inputs -// RUN: FileCheck -input-file=%t.cpp %s - -void valid() { - const int arr[5]; - int sum = 0; - for (int i = 0; i < 5; ++i) { - sum += arr[i]; - } -} -void hasSyntaxError = 3; -// CHECK: void valid() { -// CHECK-NEXT: const int arr[5]; -// CHECK-NEXT: int sum = 0; -// CHECK-NEXT: for (int i = 0; i < 5; ++i) { -// CHECK-NEXT: sum += arr[i]; -// CHECK-NEXT: } -// CHECK-NEXT: } - -// CHECK-NEXT: void hasSyntaxError = 3; diff --git a/clang-tools-extra/test/cpp11-migrate/LoopConvert/pseudoarray.cpp b/clang-tools-extra/test/cpp11-migrate/LoopConvert/pseudoarray.cpp deleted file mode 100644 index 5aeaf79fc9f..00000000000 --- a/clang-tools-extra/test/cpp11-migrate/LoopConvert/pseudoarray.cpp +++ /dev/null @@ -1,105 +0,0 @@ -// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp -// RUN: cpp11-migrate -loop-convert %t.cpp -- -I %S/Inputs -std=c++11 -// RUN: FileCheck -input-file=%t.cpp %s -#include "structures.h" - -const int N = 6; -dependent<int> v; -dependent<int> *pv; - -transparent<dependent<int> > cv; - -void f() { - int sum = 0; - for (int i = 0, e = v.size(); i < e; ++i) { - printf("Fibonacci number is %d\n", v[i]); - sum += v[i] + 2; - } - // CHECK: for (auto & elem : v) - // CHECK-NEXT: printf("Fibonacci number is %d\n", elem); - // CHECK-NEXT: sum += elem + 2; - - for (int i = 0, e = v.size(); i < e; ++i) { - printf("Fibonacci number is %d\n", v.at(i)); - sum += v.at(i) + 2; - } - // CHECK: for (auto & elem : v) - // CHECK-NEXT: printf("Fibonacci number is %d\n", elem); - // CHECK-NEXT: sum += elem + 2; - - for (int i = 0, e = pv->size(); i < e; ++i) { - printf("Fibonacci number is %d\n", pv->at(i)); - sum += pv->at(i) + 2; - } - // CHECK: for (auto & elem : *pv) - // CHECK-NEXT: printf("Fibonacci number is %d\n", elem); - // CHECK-NEXT: sum += elem + 2; - - // This test will fail if size() isn't called repeatedly, since it - // returns unsigned int, and 0 is deduced to be signed int. - // FIXME: Insert the necessary explicit conversion, or write out the types - // explicitly. - for (int i = 0; i < pv->size(); ++i) { - printf("Fibonacci number is %d\n", (*pv).at(i)); - sum += (*pv)[i] + 2; - } - // CHECK: for (auto & elem : *pv) - // CHECK-NEXT: printf("Fibonacci number is %d\n", elem); - // CHECK-NEXT: sum += elem + 2; - - for (int i = 0; i < cv->size(); ++i) { - printf("Fibonacci number is %d\n", cv->at(i)); - sum += cv->at(i) + 2; - } - // CHECK: for (auto & elem : *cv) - // CHECK-NEXT: printf("Fibonacci number is %d\n", elem); - // CHECK-NEXT: sum += elem + 2; -} - -// Check for loops that don't mention containers -void noContainer() { - for (auto i = 0; i < v.size(); ++i) { } - // CHECK: for (auto & elem : v) { } - - for (auto i = 0; i < v.size(); ++i) ; - // CHECK: for (auto & elem : v) ; -} - -struct NoBeginEnd { - unsigned size() const; -}; - -struct NoConstBeginEnd { - NoConstBeginEnd(); - unsigned size() const; - unsigned begin(); - unsigned end(); -}; - -struct ConstBeginEnd { - ConstBeginEnd(); - unsigned size() const; - unsigned begin() const; - unsigned end() const; -}; - -// Shouldn't transform pseudo-array uses if the container doesn't provide -// begin() and end() of the right const-ness. -void NoBeginEndTest() { - NoBeginEnd NBE; - for (unsigned i = 0, e = NBE.size(); i < e; ++i) {} - // CHECK: for (unsigned i = 0, e = NBE.size(); i < e; ++i) {} - - const NoConstBeginEnd const_NCBE; - for (unsigned i = 0, e = const_NCBE.size(); i < e; ++i) {} - // CHECK: for (unsigned i = 0, e = const_NCBE.size(); i < e; ++i) {} - - ConstBeginEnd CBE; - for (unsigned i = 0, e = CBE.size(); i < e; ++i) {} - // CHECK: for (auto & elem : CBE) {} - - const ConstBeginEnd const_CBE; - for (unsigned i = 0, e = const_CBE.size(); i < e; ++i) {} - // CHECK: for (auto & elem : const_CBE) {} -} - diff --git a/clang-tools-extra/test/cpp11-migrate/LoopConvert/single-iterator.cpp b/clang-tools-extra/test/cpp11-migrate/LoopConvert/single-iterator.cpp deleted file mode 100644 index a5a74c1a859..00000000000 --- a/clang-tools-extra/test/cpp11-migrate/LoopConvert/single-iterator.cpp +++ /dev/null @@ -1,152 +0,0 @@ -// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp -// RUN: cpp11-migrate -loop-convert %t.cpp -- -I %S/Inputs -// RUN: FileCheck -input-file=%t.cpp %s - -#include "structures.h" - -void complexContainer() { - X exes[5]; - int index = 0; - - for (S::iterator i = exes[index].getS().begin(), e = exes[index].getS().end(); i != e; ++i) { - MutableVal k = *i; - MutableVal j = *i; - } - // CHECK: for (auto & elem : exes[index].getS()) - // CHECK-NEXT: MutableVal k = elem; - // CHECK-NEXT: MutableVal j = elem; -} - -void f() { - /// begin()/end() - based for loops here: - T t; - for (T::iterator it = t.begin(); it != t.end(); ++it) { - printf("I found %d\n", *it); - } - // CHECK: for (auto & elem : t) - // CHECK-NEXT: printf("I found %d\n", elem); - - T *pt; - for (T::iterator it = pt->begin(); it != pt->end(); ++it) { - printf("I found %d\n", *it); - } - // CHECK: for (auto & elem : *pt) - // CHECK-NEXT: printf("I found %d\n", elem); - - S s; - for (S::iterator it = s.begin(); it != s.end(); ++it) { - printf("s has value %d\n", (*it).x); - } - // CHECK: for (auto & elem : s) - // CHECK-NEXT: printf("s has value %d\n", (elem).x); - - S *ps; - for (S::iterator it = ps->begin(); it != ps->end(); ++it) { - printf("s has value %d\n", (*it).x); - } - // CHECK: for (auto & p : *ps) - // CHECK-NEXT: printf("s has value %d\n", (p).x); - - for (S::iterator it = s.begin(); it != s.end(); ++it) { - printf("s has value %d\n", it->x); - } - // CHECK: for (auto & elem : s) - // CHECK-NEXT: printf("s has value %d\n", elem.x); - - for (S::iterator it = s.begin(); it != s.end(); ++it) { - it->x = 3; - } - // CHECK: for (auto & elem : s) - // CHECK-NEXT: elem.x = 3; - - for (S::iterator it = s.begin(); it != s.end(); ++it) { - (*it).x = 3; - } - // CHECK: for (auto & elem : s) - // CHECK-NEXT: (elem).x = 3; - - for (S::iterator it = s.begin(); it != s.end(); ++it) { - it->nonConstFun(4, 5); - } - // CHECK: for (auto & elem : s) - // CHECK-NEXT: elem.nonConstFun(4, 5); - - U u; - for (U::iterator it = u.begin(); it != u.end(); ++it) { - printf("s has value %d\n", it->x); - } - // CHECK: for (auto & elem : u) - // CHECK-NEXT: printf("s has value %d\n", elem.x); - - for (U::iterator it = u.begin(); it != u.end(); ++it) { - printf("s has value %d\n", (*it).x); - } - // CHECK: for (auto & elem : u) - // CHECK-NEXT: printf("s has value %d\n", (elem).x); - - U::iterator A; - for (U::iterator i = u.begin(); i != u.end(); ++i) - int k = A->x + i->x; - // CHECK: for (auto & elem : u) - // CHECK-NEXT: int k = A->x + elem.x; - - dependent<int> v; - for (dependent<int>::iterator it = v.begin(); - it != v.end(); ++it) { - printf("Fibonacci number is %d\n", *it); - } - // CHECK: for (auto & elem : v) { - // CHECK-NEXT: printf("Fibonacci number is %d\n", elem); - - for (dependent<int>::iterator it(v.begin()); - it != v.end(); ++it) { - printf("Fibonacci number is %d\n", *it); - } - // CHECK: for (auto & elem : v) { - // CHECK-NEXT: printf("Fibonacci number is %d\n", elem); - - doublyDependent<int,int> intmap; - for (doublyDependent<int,int>::iterator it = intmap.begin(); - it != intmap.end(); ++it) { - printf("intmap[%d] = %d", it->first, it->second); - } - // CHECK: for (auto & elem : intmap) - // CHECK-NEXT: printf("intmap[%d] = %d", elem.first, elem.second); -} - -void different_type() { - // Tests to verify the proper use of auto where the init variable type and the - // initializer type differ or are mostly the same except for const qualifiers. - - // s.begin() returns a type 'iterator' which is just a non-const pointer and - // differs from const_iterator only on the const qualification. - S s; - for (S::const_iterator it = s.begin(); it != s.end(); ++it) { - printf("s has value %d\n", (*it).x); - } - // CHECK: for (const auto & elem : s) - // CHECK-NEXT: printf("s has value %d\n", (elem).x); - - S *ps; - for (S::const_iterator it = ps->begin(); it != ps->end(); ++it) { - printf("s has value %d\n", (*it).x); - } - // CHECK: for (const auto & p : *ps) - // CHECK-NEXT: printf("s has value %d\n", (p).x); - - // v.begin() returns a user-defined type 'iterator' which, since it's - // different from const_iterator, disqualifies these loops from - // transformation. - dependent<int> v; - for (dependent<int>::const_iterator it = v.begin(); it != v.end(); ++it) { - printf("Fibonacci number is %d\n", *it); - } - // CHECK: for (dependent<int>::const_iterator it = v.begin(); it != v.end(); ++it) { - // CHECK-NEXT: printf("Fibonacci number is %d\n", *it); - - for (dependent<int>::const_iterator it(v.begin()); it != v.end(); ++it) { - printf("Fibonacci number is %d\n", *it); - } - // CHECK: for (dependent<int>::const_iterator it(v.begin()); it != v.end(); ++it) { - // CHECK-NEXT: printf("Fibonacci number is %d\n", *it); -} |

